﻿// ----------------------------------------------------------------------------------------
// Author:                    Magaly Vargas y Joaquín López
// Company:                   ALBALIA INTERACTIVA S.L.
// Assembly version:          1.0.0.0
// Date:                      22/02/2010
// Time:                      12:00
// Solution Name:             OffInvoiceWordAddIn
// Solution Filename:         OffInvoiceWordAddIn
// Solution FullFilename:     C:\Desarrollo\OffInvoiceWordAddIn
// Project Name:              OffInvoiceWordAddIn
// Project Filename:          OffInvoiceWordAddIn.csproj
// Project FullFilename:      C:\Desarrollo\OffInvoiceWordAddIn\OffInvoiceWordAddIn.csproj
// Project Item Name:         InvoiceValidations.cs
// Project Item Filename:     InvoiceValidations.cs
// Project Item FullFilename: C:\Desarrollo\OffInvoiceWordAddIn\InvoiceValidations.cs
// Project Item Kind:         Código
// Purpose:                   
//Copyright © 2009 - 2010 Albalia Interactiva S.L. Reservados todos los derechos.
// ----------------------------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Threading;
using System.Globalization;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using OffInvoiceWordAddIn.FacturaeFiles;
using System.Reflection;
using OffInvoiceWordAddIn.CIIFiles;
using OffInvoiceWordAddIn.UBLFiles;

namespace OffInvoiceWordAddIn
{
    /// <summary>
    /// Clase que se encarcaga de las validaciones.
    /// </summary>
    public static class InvoiceValidations
    {


        #region "Public Methods"

        /// <summary>
        /// Validación contable de Facturae v3.1
        /// </summary>
        /// <param name="doc">Documento xml con la facturae</param>
        public static void ValidationAccountingV31(XmlDocument doc)
        {
            ControlMessages msg = ControlMessages.getInstance();
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            // Recuperamos el nodo inicial de la factura (el documento podría venir incluido
            // en otro, como un documento SOAP por ejemplo)

            XmlElement raiz = (XmlElement)doc.DocumentElement;

            // Bloques
            XmlElement cabecera = (XmlElement)raiz.GetElementsByTagName("FileHeader").Item(0);
            XmlElement sujetos = (XmlElement)raiz.GetElementsByTagName("Parties").Item(0);
            XmlElement facturas = (XmlElement)raiz.GetElementsByTagName("Invoices").Item(0);

            // Nivel 1
            XmlElement tercero = null;
            XmlElement datosCesionFactoring = null;
            XmlElement lote = (XmlElement)cabecera.GetElementsByTagName("Batch").Item(0);
            XmlElement emisor = (XmlElement)sujetos.GetElementsByTagName("SellerParty").Item(0);
            XmlElement receptor = (XmlElement)sujetos.GetElementsByTagName("BuyerParty").Item(0);
            XmlNodeList nodosFacturas = facturas.GetElementsByTagName("Invoice");

            // VALIDACIONES DEL NODO CABECERA

            // Modalidad

            // Para la modalidad individual (I) el número de facturas debe ser 1
            String modalidad = ((XmlElement)cabecera.GetElementsByTagName("Modality").Item(0)).FirstChild.Value;
            String numFacturas = ((XmlElement)cabecera.GetElementsByTagName("InvoicesCount").Item(0)).FirstChild.Value;
            if (modalidad.Equals("I"))
            {
                if (Int16.Parse(numFacturas) != 1)
                {

                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityI));
                }
            }
            else
            {
                if (Int16.Parse(numFacturas) <= 1)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityL));
                }
            }

            // TipoEmisorFactura

            // Para TipoEmisorFactura TE debe existir el nodo Tercero 
            String tipoEmisorFactura = ((XmlElement)cabecera.GetElementsByTagName("InvoiceIssuerType").Item(0)).FirstChild.Value;
            if (tipoEmisorFactura.Equals("TE"))
            {
                XmlNodeList nlst = cabecera.GetElementsByTagName("ThirdParty");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceIssuerTypeTE));
                }
                else
                {
                    // Tercero	
                    // Correspondencia del tipo de persona con los datos
                    tercero = (XmlElement)nlst.Item(0);
                    String tipoDePersona = ((XmlElement)tercero.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;
                    if (tipoDePersona.Equals("F"))
                    {
                        nlst = tercero.GetElementsByTagName("Individual");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorPersonTypeCodeF));
                        }
                        else
                        {
                            XmlElement personaFisica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                    else
                    {
                        nlst = tercero.GetElementsByTagName("LegalEntity");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeJ));
                        }
                        else
                        {
                            XmlElement personaJuridica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                }
            }

            // Lote

            XmlElement totalFacturas = (XmlElement)lote.GetElementsByTagName("TotalInvoicesAmount").Item(0);
            XmlElement totalAPagar = (XmlElement)lote.GetElementsByTagName("TotalOutstandingAmount").Item(0);
            XmlElement totalAEjecutar = (XmlElement)lote.GetElementsByTagName("TotalExecutableAmount").Item(0);
            String moneda = ((XmlElement)lote.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;
            
            ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)
            //////if (moneda.Equals("EUR"))
            //////{
            //////    /*			// Si la moneda es euro, el ImporteTotal de TotalFacturas debe tener 2 decimales
            //////                String importe = ((Element)totalFacturas.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(8,"ImporteTotal de TotalFacturas no tiene 2 decimales");
            //////                }

            //////                // Si la moneda es euro, el ImporteTotal de TotalAPagar debe tener 2 decimales
            //////                importe = ((Element)totalAPagar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(9,"ImporteTotal de TotalAPagar no tiene 2 decimales");
            //////                }
    			
            //////                // Si la moneda es euro, el ImporteTotal de TotalAEjecutar debe tener 2 decimales
            //////                importe = ((Element)totalAEjecutar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(10,"ImporteTotal de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////    */
            //////}
            //////else
            //////{
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalFacturas
            //////    XmlNodeList nlst = totalFacturas.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalInvoicesAmountEquivalentInEuros));
            //////    }
            //////    // El número de decimales del cambio debe ser 2
            //////    /*			String tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(12,"TipoCambio de TotalFacturas no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                String importe = ((Element)totalFacturas.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(13,"ContravalorEuros de TotalFacturas no tiene 2 decimales");
            //////                }
    			
            //////    */
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalAPagar
            //////    nlst = totalAPagar.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmountEquivalentInEuros));
            //////    }
            //////    /*			// El número de decimales del cambio debe ser 2
            //////                tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(15,"TipoCambio de TotalAPagar no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                importe = ((Element)totalAPagar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(16,"ContravalorEuros de TotalAPagar no tiene 2 decimales");
            //////                }
    			
            //////    */
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalAEjecutar
            //////    nlst = totalAEjecutar.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmountEquivalentInEuros));
            //////    }
            //////    /*			// El número de decimales del cambio debe ser 2
            //////                tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(18,"TipoCambio de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                importe = ((Element)totalAEjecutar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(19,"ContravalorEuros de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////    */
            //////}
            //Comprobamos que ImporteTotal de TotalFacturas, TotalAPagar y TotalAEjecutar coincide con la suma de los importes de cada factura
            String importeTotalFacturas = ((XmlElement)totalFacturas.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAPagar = ((XmlElement)totalAPagar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAEjecutar = ((XmlElement)totalAEjecutar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            if ((((Double.Parse(importeTotalFacturas)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAPagar)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAEjecutar)).CompareTo(0)) != 0))
            {
                double sumaTotalFacturas = 0;
                double sumaTotalAPagar = 0;
                double sumaTotalAEjecutar = 0;
                for (int i = 0; i < nodosFacturas.Count; i++)
                {
                    XmlElement factura = ((XmlElement)nodosFacturas.Item(i));
                    String totalFacturasInd = ((XmlElement)factura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                    sumaTotalFacturas += Double.Parse(totalFacturasInd);
                    String totalAPagarInd = ((XmlElement)factura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                    sumaTotalAPagar += Double.Parse(totalAPagarInd);
                    String totalAEjecutarInd = ((XmlElement)factura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                    sumaTotalAEjecutar += Double.Parse(totalAEjecutarInd);
                }
                if (((Double.Parse(importeTotalFacturas)).CompareTo(redondeo(sumaTotalFacturas))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountInvoiceTotal));
                }
                if (((Double.Parse(importeTotalAPagar)).CompareTo(redondeo(sumaTotalAPagar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalOutstandingAmount));
                }
                if (((Double.Parse(importeTotalAEjecutar)).CompareTo(redondeo(sumaTotalAEjecutar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalExecutableAmount));
                }
            }

            // DatosCesionFactoring

            // Correspondencia del tipo de persona con los datos
            XmlNodeList nl = cabecera.GetElementsByTagName("FactoringAssignmentData");
            if (nl.Count != 0)
            {
                datosCesionFactoring = (XmlElement)nl.Item(0);
                String tipoDePersona = ((XmlElement)datosCesionFactoring.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

                if (tipoDePersona.Equals("F"))
                {
                    nl = datosCesionFactoring.GetElementsByTagName("Individual");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeF));
                    }
                    else
                    {
                        XmlElement personaFisica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
                else
                {
                    nl = datosCesionFactoring.GetElementsByTagName("LegalEntity");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeJ));
                    }
                    else
                    {
                        XmlElement personaJuridica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
            }

            // VALIDACIONES DEL NODO SUJETOS

            // Emisor

            //comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = emisor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            // Correspondencia del tipo de persona con los datos
            String tipoPersona = ((XmlElement)emisor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = emisor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = emisor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Receptor

            //	comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = receptor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Correspondencia del tipo de persona con los datos
            tipoPersona = ((XmlElement)receptor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = receptor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = receptor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }


            // VALIDACIONES DEL NODO FACTURAS

            // Como puede haber mas de una factura las recorremos una a una haciendo todas las validaciones
            for (int i = 0; i < nodosFacturas.Count; i++)
            {
                XmlElement factura = ((XmlElement)nodosFacturas.Item(i));

                // Si la clase de factura es rectificativa, debe venir el nodo Rectificativa
                String clase = ((XmlElement)factura.GetElementsByTagName("InvoiceClass").Item(0)).FirstChild.Value;
                if (clase.Equals("OR") || clase.Equals("CR"))
                {
                    nl = factura.GetElementsByTagName("Corrective");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrective));
                    }
                    else
                    {
                        // Comprobamos que DescripcionCriterioRectificacion corresponde con el código elegido en CriterioRectificacion
                        XmlElement rectificaciva = (XmlElement)nl.Item(0);
                        String criterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethod").Item(0)).FirstChild.Value;
                        String decripcionCriterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethodDescription").Item(0)).FirstChild.Value;
                        //if (!(criterioRectificacion.Equals("01") && decripcionCriterioRectificacion.Equals("Rectificación íntegra")) &&
                        //        !(criterioRectificacion.Equals("02") && decripcionCriterioRectificacion.Equals("Rectificación por diferencias")))
                        //{
                        //    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrectionMethodDescription));
                        //}

                        //MODIFIQUE ESTE METODO PORQUE NO LE ENCONTRE LÓGICA YA QUE NUNCA SE CUMPLIRÍA

                        if (((decripcionCriterioRectificacion.Equals("Rectificación íntegra") || decripcionCriterioRectificacion.Equals("Full items")) && !criterioRectificacion.Equals("01")) || ((decripcionCriterioRectificacion.Equals("Rectificación por diferencias") || decripcionCriterioRectificacion.Equals("Corrected items only")) && !criterioRectificacion.Equals("02")) || ((decripcionCriterioRectificacion.Equals("Rectificación por descuento por volumen de operaciones durante un periodo") || decripcionCriterioRectificacion.Equals("Bulk deal in a given period")) && !criterioRectificacion.Equals("03")) || ((decripcionCriterioRectificacion.Equals("Autorizadas por la Agencia Tributaria") || decripcionCriterioRectificacion.Equals("Authorized by the Tax Agency")) && !criterioRectificacion.Equals("04")))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrectionMethodDescription));
                        }

                    }
                }
                //Si la clase es OC o CC, debe venir el nodo PeriodoFacturacion
                else if (clase.Equals("OC") || clase.Equals("CC"))
                {
                    nl = factura.GetElementsByTagName("InvoicingPeriod");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassInvoicingPeriod));
                    }
                }

                // MonedaImpuesto siempre debe ser EUR
                moneda = ((XmlElement)factura.GetElementsByTagName("TaxCurrencyCode").Item(0)).FirstChild.Value;
                if (!moneda.Equals("EUR"))
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxCurrencyCode));
                }

                moneda = ((XmlElement)factura.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;



                // Totales factura

                XmlElement totalesFactura = (XmlElement)factura.GetElementsByTagName("InvoiceTotals").Item(0);

                // El número de decimales del TotalImporteBruto debe ser 2
                String totalImporteBruto = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmount").Item(0)).FirstChild.Value;
                double dTotalImporteBruto = Double.Parse(totalImporteBruto);
                /*			if(decimales(totalImporteBruto) != 2)
                            {
                                throw new Exception(61,"TotalImporteBruto de la factura no tiene 2 decimales");
                            }
                */


                // ImpuestosRepercutidos
                XmlElement impuestosRepercutidos = (XmlElement)factura.GetElementsByTagName("TaxesOutputs").Item(0);
                XmlNodeList nodosImpuestosRepercutidos = impuestosRepercutidos.GetElementsByTagName("Tax");
                XmlElement baseImponible = null;
                XmlElement cuota = null;
                double sumaImpuestosRepercutidos = 0;
                for (int j = 0; j < nodosImpuestosRepercutidos.Count; j++)
                {
                    XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidos.Item(j));
                    baseImponible = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                    cuota = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                    String importeBaseImponible = null;
                    String importeCuota = null;
                    String tipo = null;

                    // El número de decimales del PorcentajeImpuesto debe ser 2
                    XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                    String valorPorcentajeImpuesto = null;
                    if (porcentajeImpuesto != null)
                    {
                        valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                        if (decimales(valorPorcentajeImpuesto) != 2)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                        }
                    }

                    /************* CODIGO AUXILIAR HASTA SOLUCION ***************/

                    if (baseImponible != null)
                    {
                        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        /*						if(decimales(importeBaseImponible) != 2)
                                                {
                                                    throw new Exception(42,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                }
                        */
                        // La base imponible no puede superar el importe bruto
                        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBase));
                        }
                    }
                    if (cuota != null)
                    {
                        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        /*						if(decimales(importeCuota) != 2)
                                                {
                                                    throw new Exception(43,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                }
                        */
                    }
                  





                    ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)
                    //////if (moneda.Equals("EUR"))
                    //////{
                    //////    if (baseImponible != null)
                    //////    {
                    //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                    //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeBaseImponible) != 2)
                    //////                                {
                    //////                                    throw new Exception(42,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // La base imponible no puede superar el importe bruto
                    //////        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBase));
                    //////        }
                    //////    }
                    //////    if (cuota != null)
                    //////    {
                    //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeCuota) != 2)
                    //////                                {
                    //////                                    throw new Exception(43,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////    }
                    //////}
                    //////else
                    //////{
                    //////    if (baseImponible != null)
                    //////    {
                    //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                    //////        nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                    //////        if (nl.Count == 0)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                    //////        }
                    //////        // El número de decimales del cambio debe ser 2
                    //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(tipo) != 2)
                    //////                                {
                    //////                                    throw new Exception(45,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // El número de decimales del contravalor en euros debe ser 2
                    //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeBaseImponible) != 2)
                    //////                                {
                    //////                                    throw new Exception(46,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }					
                    //////        */
                    //////    }
                    //////    if (cuota != null)
                    //////    {
                    //////        nl = cuota.GetElementsByTagName("EquivalentInEuros");
                    //////        if (nl.Count == 0)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsTaxAmountEquivalentInEuros));
                    //////        }
                    //////        // El número de decimales del cambio debe ser 2
                    //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(tipo) != 2)
                    //////                                {
                    //////                                    throw new Exception(48,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // El número de decimales del contravalor en euros debe ser 2
                    //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeCuota) != 2)
                    //////                                {
                    //////                                    throw new Exception(49,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////    }
                    //////}


                    // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                    if (cuota != null)
                    {
                        if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                        {
                            double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                            if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsPercent));
                            }
                        }

                        // Sumamos los importes de todas las cuotas para utilizarlos despues
                        sumaImpuestosRepercutidos += Double.Parse(importeCuota);
                    }
                }

                // ImpuestosRetenidos
                double sumaImpuestosRetenidos = 0;
                nl = factura.GetElementsByTagName("TaxesWithheld");
                if (nl.Count > 0)
                {
                    XmlElement impuestosRetenidos = (XmlElement)nl.Item(0);
                    XmlNodeList nodosImpuestosRetenidos = impuestosRetenidos.GetElementsByTagName("Tax");
                    for (int j = 0; j < nodosImpuestosRetenidos.Count; j++)
                    {
                        XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidos.Item(j));
                        baseImponible = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                        cuota = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                            }
                        }


                        /************* CODIGO AUXILIAR HASTA SOLUCION ***************/

                        if (baseImponible != null)
                        {
                            // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeBaseImponible) != 2)
                                                        {
                                                            throw new Exception(52,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                        }
                            */
                            // La base imponible no puede superar el importe bruto
                            if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseTotalAmount));
                            }
                        }
                        if (cuota != null)
                        {
                            importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeCuota) != 2)
                                                        {
                                                            throw new Exception(53,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                        }
                            */
                        }


                        ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)

                        //////if (moneda.Equals("EUR"))
                        //////{
                        //////    if (baseImponible != null)
                        //////    {
                        //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(52,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // La base imponible no puede superar el importe bruto
                        //////        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseTotalAmount));
                        //////        }
                        //////    }
                        //////    if (cuota != null)
                        //////    {
                        //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(53,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}
                        //////else
                        //////{
                        //////    if (baseImponible != null)
                        //////    {
                        //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                        //////        nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(55,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(56,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }					
                        //////        */
                        //////    }
                        //////    if (cuota != null)
                        //////    {
                        //////        nl = cuota.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(58,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(59,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuota != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                }
                            }

                            // Sumamos los importes de todas las cuotas para utilizarlos despues
                            sumaImpuestosRetenidos += Double.Parse(importeCuota);
                        }
                    }
                }

                // Comprobacion del nodo DescuentosGenerales
                XmlElement descuentosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralDiscounts").Item(0);
                double sumaImportesDescuento = 0;
                if (descuentosGenerales != null)
                {
                    XmlNodeList nodosDescuentos = descuentosGenerales.GetElementsByTagName("Discount");
                    for (int k = 0; k < nodosDescuentos.Count; k++)
                    {
                        XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                        // El número de decimales del PorcentajeDescuento debe ser 4
                        XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                        if (porcentajeDescuento != null)
                        {
                            String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                            if (decimales(valorPorcentajeDescuento) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralDiscounts));
                            }
                        }
                        // El número de decimales del ImporteDescuento debe ser 2
                        String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeDescuento) != 2)
                                            {
                                                throw new Exception(63,"ImporteDescuento no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesDescuento += Double.Parse(importeDescuento);
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo RecargosGenerales
                XmlElement recargosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralSurcharges").Item(0);
                double sumaImportesCargo = 0;
                if (recargosGenerales != null)
                {
                    XmlNodeList nodosRecargos = recargosGenerales.GetElementsByTagName("Charge");
                    for (int k = 0; k < nodosRecargos.Count; k++)
                    {
                        XmlElement cargo = ((XmlElement)nodosRecargos.Item(k));
                        // El número de decimales del PorcentajeCargo debe ser 4
                        XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                        if (porcentajeCargo != null)
                        {
                            String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                            if (decimales(valorPorcentajeCargo) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralSurcharges));
                            }
                        }
                        // El número de decimales del ImporteCargo debe ser 2
                        String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeCargo) != 2)
                                            {
                                                throw new Exception(65,"ImporteCargo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesCargo += Double.Parse(importeCargo);
                        /*					}
                        */
                    }
                }

                // El número de decimales del TotalDescuentosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteDescuento
                XmlElement totalDescuentosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralDiscounts").Item(0));
                if (totalDescuentosGenerales != null)
                {
                    String valorTotalDescuentosGenerales = totalDescuentosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalDescuentosGenerales) != 2)
                                    {
                                        throw new Exception(66,"TotalDescuentosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalDescuentosGenerales)).CompareTo(redondeo(sumaImportesDescuento))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralDiscounts));
                    }
                    /*				}
                    */
                }

                // El número de decimales del TotalCargosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteCargo
                XmlElement totalCargosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralSurcharges").Item(0));
                if (totalCargosGenerales != null)
                {
                    String valorTotalCargosGenerales = totalCargosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalCargosGenerales) != 2)
                                    {
                                        throw new Exception(68,"TotalCargosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalCargosGenerales)).CompareTo(redondeo(sumaImportesCargo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralSurcharges));
                    }
                    /*				}
                    */
                }

                //TotalImporteBrutoAntesImpuestos = TotalImporteBruto - TotalDescuentosGenerales + TotalCargosGenerales
                String totalImporteBrutoAntesImpuestos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmountBeforeTaxes").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImporteBrutoAntesImpuestos) != 2)
                            {
                                throw new Exception(70,"TotalImporteBrutoAntesImpuestos no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaImporteBrutoAntesImpuestos = Double.Parse(totalImporteBruto) - sumaImportesDescuento + sumaImportesCargo;
                if (((Double.Parse(totalImporteBrutoAntesImpuestos)).CompareTo(redondeo(sumaImporteBrutoAntesImpuestos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGrossAmountBeforeTaxes));
                }
                /*			}
                */
                // TotalImpuestosRepercutidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos repercutidos
                String totalImpuestosRepercutidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxOutputs").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImpuestosRepercutidos) != 2)
                            {
                                throw new Exception(72,"TotalImpuestosRepercutidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRepercutidos)).CompareTo(redondeo(sumaImpuestosRepercutidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxOutputs));
                }
                /*			}
                */
                // TotalImpuestosRetenidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos retenidos
                String totalImpuestosRetenidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxesWithheld").Item(0)).FirstChild.Value;
                /*			if(!totalImpuestosRetenidos.equals("0") && decimales(totalImpuestosRetenidos) != 2)
                            {
                                throw new Exception(74,"TotalImpuestosRetenidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRetenidos)).CompareTo(redondeo(sumaImpuestosRetenidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxesWithheld));
                }
                /*			}
                */
                // TotalFactura = TotalImporteBrutoAntesImpuestos + TotalImpuestosRepercutidos - TotalImpuestosRetenidos
                String totalfactura = ((XmlElement)totalesFactura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                /*			if(decimales(totalfactura) != 2)
                            {
                                throw new Exception(76,"Totalfactura no tiene 2 decimales");
                            }
                            else
                            {
                */
                double total = Double.Parse(totalImporteBrutoAntesImpuestos) + (Double.Parse(totalImpuestosRepercutidos) - Double.Parse(totalImpuestosRetenidos));
                if (((Double.Parse(totalfactura)).CompareTo(redondeo(total))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceTotal));
                }
                /*			}
                */
                // Comprobacion del nodo Subvenciones
                XmlElement subvenciones = (XmlElement)totalesFactura.GetElementsByTagName("Subsidies").Item(0);
                double sumaImportesSubvencion = 0;
                if (subvenciones != null)
                {
                    XmlNodeList nodosSubvenciones = subvenciones.GetElementsByTagName("Subsidy");
                    for (int j = 0; j < nodosSubvenciones.Count; j++)
                    {
                        XmlElement subvencion = ((XmlElement)nodosSubvenciones.Item(j));
                        // El número de decimales del PorcentajeSubvencion debe ser 4
                        XmlElement porcentajeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyRate").Item(0));
                        if (porcentajeSubvencion != null)
                        {
                            String valorPorcentajeSubvencion = porcentajeSubvencion.FirstChild.Value;
                            if (decimales(valorPorcentajeSubvencion) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSubsidyRate));
                            }
                        }
                        // El número de decimales del ImporteSubvencion debe ser 2
                        String importeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeSubvencion) != 2)
                                            {
                                                throw new Exception(79,"ImporteSubvencion no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesSubvencion += Double.Parse(importeSubvencion);
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo Anticipos
                XmlElement anticipos = (XmlElement)totalesFactura.GetElementsByTagName("PaymentsonAccount").Item(0);
                double sumaImportesAnticipo = 0;
                if (anticipos != null)
                {
                    XmlNodeList nodosAnticipos = anticipos.GetElementsByTagName("PaymentOnAccount");
                    for (int j = 0; j < nodosAnticipos.Count; j++)
                    {
                        XmlElement anticipo = ((XmlElement)nodosAnticipos.Item(j));
                        // El número de decimales del ImporteAnticipo debe ser 2
                        String importeAnticipo = ((XmlElement)anticipo.GetElementsByTagName("PaymentOnAccountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeAnticipo) != 2)
                                            {
                                                throw new Exception(80,"ImporteAnticipo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesAnticipo += Double.Parse(importeAnticipo);
                        /*					}
                        */
                    }
                }

                // TotalAnticipos debe coincidir con el sumatorio de los importes de los anticipos
                XmlElement totalAnticipos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalPaymentsOnAccount").Item(0));
                if (totalAnticipos != null)
                {
                    String valorTotalAnticipos = totalAnticipos.FirstChild.Value;
                    /*				if(decimales(valorTotalAnticipos) != 2)
                                    {
                                        throw new Exception(81,"TotalAnticipos no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalAnticipos)).CompareTo(redondeo(sumaImportesAnticipo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalPaymentsOnAccount));
                    }
                    /*				}
                    */
                }

                // TotalAPagar = TotalFactura - (Sumatorio de ImporteSubvencion + TotalAnticipos)
                String totalAPagarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAPagarFactura) != 2)
                            {
                                throw new Exception(83,"TotalAPagar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAPagarFactura = Double.Parse(totalfactura) - (sumaImportesSubvencion + sumaImportesAnticipo);
                if (((Double.Parse(totalAPagarFactura)).CompareTo(redondeo(sumaAPagarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmount));
                    /*				}
                    */
                }

                // Comprobacion del nodo RetencionGarantia
                XmlElement retencionGarantia = (XmlElement)totalesFactura.GetElementsByTagName("AmountsWithheld").Item(0);
                double valorImporteRetencion = 0;
                if (retencionGarantia != null)
                {
                    // El número de decimales del PorcentajeRetencion debe ser 4
                    XmlElement porcentajeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingRate").Item(0));
                    if (porcentajeRetencion != null)
                    {
                        String valorPorcentajeRetencion = porcentajeRetencion.FirstChild.Value;
                        if (decimales(valorPorcentajeRetencion) != 4)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorWithholdingRate));
                        }
                    }
                    // El número de decimales del ImporteRetencion debe ser 2
                    String importeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeRetencion) != 2)
                                    {
                                        throw new Exception(86,"ImporteRetencion no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    valorImporteRetencion = Double.Parse(importeRetencion);
                    /*				}
                    */
                }

                // TotalAEjecutar = TotalAPagar - ImporteRetencion
                String totalAEjecutarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAEjecutarFactura) != 2)
                            {
                                throw new Exception(87,"TotalAEjecutar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAEjecutarFactura = Double.Parse(totalAPagarFactura) - valorImporteRetencion;
                if (((Double.Parse(totalAEjecutarFactura)).CompareTo(redondeo(sumaAEjecutarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmount));
                }
                /*			}
                */
                // Detalles

                XmlElement detalles = ((XmlElement)factura.GetElementsByTagName("Items").Item(0));
                XmlNodeList nodosDetalles = detalles.GetElementsByTagName("InvoiceLine");
                double sumaImporteBruto = 0;
                for (int j = 0; j < nodosDetalles.Count; j++)
                {
                    XmlElement detalle = ((XmlElement)nodosDetalles.Item(j));

                    // El número de decimales del PrecioUnitarioSinImpuestos debe ser 2
                    String precioUnitarioSinImpuestos = ((XmlElement)detalle.GetElementsByTagName("UnitPriceWithoutTax").Item(0)).FirstChild.Value;
                    /*				if(decimales(precioUnitarioSinImpuestos) != 6)
                                    {
                                        throw new Exception(89,"PrecioUnitarioSinImpuestos no tiene 6 decimales");
                                    }
                    */
                    //Comprobar que CosteTotal = Cantidad * PrecioUnitarioSinImpuestos
                    String cantidad = ((XmlElement)detalle.GetElementsByTagName("Quantity").Item(0)).FirstChild.Value;
                    String costeTotal = ((XmlElement)detalle.GetElementsByTagName("TotalCost").Item(0)).FirstChild.Value;
                    /*				if(decimales(costeTotal) != 2)
                                    {
                                        throw new Exception(90,"CosteTotal no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double sumaCosteTotal = Double.Parse(precioUnitarioSinImpuestos) * Double.Parse(cantidad);
                    if (((Double.Parse(costeTotal)).CompareTo(redondeo(sumaCosteTotal))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalCost));
                    }
                    /*				}
                    */
                    // Comprobacion del nodo Descuentos
                    XmlElement descuentos = (XmlElement)detalle.GetElementsByTagName("DiscountsAndRebates").Item(0);
                    double sumaImportesDescuentoDetalle = 0;
                    if (descuentos != null)
                    {
                        XmlNodeList nodosDescuentos = descuentos.GetElementsByTagName("Discount");
                        for (int k = 0; k < nodosDescuentos.Count; k++)
                        {
                            XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                            // El número de decimales del PorcentajeDescuento debe ser 4
                            XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                            if (porcentajeDescuento != null)
                            {
                                String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                                if (decimales(valorPorcentajeDescuento) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorDiscountRate));
                                }
                            }
                            // El número de decimales del ImporteDescuento debe ser 2
                            String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeDescuento) != 2)
                                                    {
                                                        throw new Exception(93,"ImporteDescuento no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesDescuentoDetalle += Double.Parse(importeDescuento);
                            /*						}
                            */
                        }
                    }

                    // Comprobacion del nodo Cargos
                    XmlElement cargos = (XmlElement)detalle.GetElementsByTagName("Charges").Item(0);
                    double sumaImportesCargoDetalle = 0;
                    if (cargos != null)
                    {
                        XmlNodeList nodosCargos = cargos.GetElementsByTagName("Charge");
                        for (int k = 0; k < nodosCargos.Count; k++)
                        {
                            XmlElement cargo = ((XmlElement)nodosCargos.Item(k));
                            // El número de decimales del PorcentajeCargo debe ser 4
                            XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                            if (porcentajeCargo != null)
                            {
                                String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                                if (decimales(valorPorcentajeCargo) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorChargeRate));
                                }
                            }
                            // El número de decimales del ImporteCargo debe ser 2
                            String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeCargo) != 2)
                                                    {
                                                        throw new Exception(95,"ImporteCargo no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesCargoDetalle += Double.Parse(importeCargo);
                            /*						}
                            */
                        }
                    }

                    // Comprobar que ImporteBruto = CosteTotal - Sumatorio de ImporteDescuento + Sumatorio de ImporteCargo
                    String importeBruto = ((XmlElement)detalle.GetElementsByTagName("GrossAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeBruto) != 2)
                                    {
                                        throw new Exception(96,"ImporteBruto no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double suma = Double.Parse(costeTotal) - sumaImportesDescuentoDetalle + sumaImportesCargoDetalle;
                    if (((Double.Parse(importeBruto)).CompareTo(redondeo(suma))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGrossAmount));
                    }
                    else
                    {
                        sumaImporteBruto += Double.Parse(importeBruto);
                    }
                    /*				}
                    */
                    // ImpuestosRetenidos
                    XmlElement baseImponibleDetalle = null;
                    XmlElement cuotaDetalle = null;
                    nl = detalle.GetElementsByTagName("TaxesWithheld");
                    if (nl.Count > 0)
                    {
                        XmlElement impuestosRetenidosDetalle = (XmlElement)nl.Item(0);
                        XmlNodeList nodosImpuestosRetenidosDetalle = impuestosRetenidosDetalle.GetElementsByTagName("Tax");
                        for (int k = 0; k < nodosImpuestosRetenidosDetalle.Count; k++)
                        {
                            XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidosDetalle.Item(k));
                            baseImponibleDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                            cuotaDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                            String importeBaseImponible = null;
                            String importeCuota = null;
                            String tipo = null;

                            // El número de decimales del PorcentajeImpuesto debe ser 2
                            XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                            String valorPorcentajeImpuesto = null;
                            if (porcentajeImpuesto != null)
                            {
                                valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                                if (decimales(valorPorcentajeImpuesto) != 2)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                                }
                            }
                            
                            
                            
                            /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                            if (baseImponibleDetalle != null)
                            {
                                // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                                importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*								if(decimales(importeBaseImponible) != 2)
                                                                {
                                                                    throw new Exception(109,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                                }
                                */
                            }
                            if (cuotaDetalle != null)
                            {
                                importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*								if(decimales(importeCuota) != 2)
                                                                {
                                                                    throw new Exception(110,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                                }
                                */
                            }


                            ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)
                            //////if (moneda.Equals("EUR"))
                            //////{
                            //////    if (baseImponibleDetalle != null)
                            //////    {
                            //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeBaseImponible) != 2)
                            //////                                        {
                            //////                                            throw new Exception(109,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////    if (cuotaDetalle != null)
                            //////    {
                            //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeCuota) != 2)
                            //////                                        {
                            //////                                            throw new Exception(110,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////}
                            //////else
                            //////{
                            //////    if (baseImponibleDetalle != null)
                            //////    {
                            //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                            //////        nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                            //////        if (nl.Count == 0)
                            //////        {
                            //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                            //////        }
                            //////        // El número de decimales del cambio debe ser 2
                            //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(tipo) != 2)
                            //////                                        {
                            //////                                            throw new Exception(112,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////        // El número de decimales del contravalor en euros debe ser 2
                            //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeBaseImponible) != 2)
                            //////                                        {
                            //////                                            throw new Exception(113,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }					
                            //////        */
                            //////    }
                            //////    if (cuotaDetalle != null)
                            //////    {
                            //////        nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                            //////        if (nl.Count == 0)
                            //////        {
                            //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                            //////        }
                            //////        // El número de decimales del cambio debe ser 2
                            //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(tipo) != 2)
                            //////                                        {
                            //////                                            throw new Exception(115,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////        // El número de decimales del contravalor en euros debe ser 2
                            //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeCuota) != 2)
                            //////                                        {
                            //////                                            throw new Exception(116,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////}

                            // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                            if (cuotaDetalle != null)
                            {
                                if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                                {
                                    double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                    if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                    }
                                }
                            }
                        }
                    }

                    // ImpuestosRepercutidos
                    XmlElement impuestosRepercutidosDetalle = (XmlElement)detalle.GetElementsByTagName("TaxesOutputs").Item(0);
                    XmlNodeList nodosImpuestosRepercutidosDetalle = impuestosRepercutidosDetalle.GetElementsByTagName("Tax");
                    for (int k = 0; k < nodosImpuestosRepercutidosDetalle.Count; k++)
                    {
                        XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidosDetalle.Item(k));
                        baseImponibleDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                        cuotaDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                            }
                        }


                        /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                        if (baseImponibleDetalle != null)
                        {
                            // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeBaseImponible) != 2)
                                                        {
                                                            throw new Exception(99,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                        }
                            */
                        }
                        if (cuotaDetalle != null)
                        {
                            importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeCuota) != 2)
                                                        {
                                                            throw new Exception(100,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                        }
                            */
                        }


                        ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)

                        //////if (moneda.Equals("EUR"))
                        //////{
                        //////    if (baseImponibleDetalle != null)
                        //////    {
                        //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(99,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////    if (cuotaDetalle != null)
                        //////    {
                        //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(100,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}
                        //////else
                        //////{
                        //////    if (baseImponibleDetalle != null)
                        //////    {
                        //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                        //////        nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(102,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(103,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }					
                        //////        */
                        //////    }
                        //////    if (cuotaDetalle != null)
                        //////    {
                        //////        nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(105,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(106,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuotaDetalle != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                }
                            }
                        }

                    }
                }

                // Comprobar que la suma de los importes brutos de los detalles coincide con el total
                if (((Double.Parse(totalImporteBruto)).CompareTo(redondeo(sumaImporteBruto))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSumGrossAmount));
                }

                // DatosCobro

                nl = factura.GetElementsByTagName("PaymentDetails");
                if (nl.Count > 0)
                {
                    XmlElement datosCobro = (XmlElement)nl.Item(0);
                    XmlNodeList nodosVencimiento = datosCobro.GetElementsByTagName("Installment");
                    for (int j = 0; j < nodosVencimiento.Count; j++)
                    {
                        XmlElement vencimiento = ((XmlElement)nodosVencimiento.Item(j));

                        // El número de decimales del ImporteVencimiento debe ser 2
                        String importeVencimiento = ((XmlElement)vencimiento.GetElementsByTagName("InstallmentAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeVencimiento) != 2)
                                            {
                                                throw new Exception(119,"ImporteVencimiento no tiene 2 decimales");
                                            }
                        */
                        // Si FormaPago es "Trasferencia", el nodo CuentaAbono es obligatorio
                        String formaPago = ((XmlElement)vencimiento.GetElementsByTagName("PaymentMeans").Item(0)).FirstChild.Value;
                        if (formaPago.Equals("Transferencia"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeCredited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeCredited));
                            }
                            else
                            {
                                XmlElement cuentaAbono = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaAbono.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                        // Si FormaPago es "Recibo", el nodo CuentaCargo es obligatorio
                        else if (formaPago.Equals("Recibo"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeDebited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeDebited));
                            }
                            else
                            {
                                XmlElement cuentaCargo = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaCargo.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // <summary>
        /// Validación contable de Facturae v3.2
        /// </summary>
        /// <param name="doc">Documento xml con la facturae</param>
        public static void ValidationAccountingV32(XmlDocument doc)
        {
            ControlMessages msg = ControlMessages.getInstance();
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            // Recuperamos el nodo inicial de la factura (el documento podría venir incluido
            // en otro, como un documento SOAP por ejemplo)

            XmlElement raiz = (XmlElement)doc.DocumentElement;

            // Bloques
            XmlElement cabecera = (XmlElement)raiz.GetElementsByTagName("FileHeader").Item(0);
            XmlElement sujetos = (XmlElement)raiz.GetElementsByTagName("Parties").Item(0);
            XmlElement facturas = (XmlElement)raiz.GetElementsByTagName("Invoices").Item(0);

            // Nivel 1
            XmlElement tercero = null;
            XmlElement datosCesionFactoring = null;
            XmlElement lote = (XmlElement)cabecera.GetElementsByTagName("Batch").Item(0);
            XmlElement emisor = (XmlElement)sujetos.GetElementsByTagName("SellerParty").Item(0);
            XmlElement receptor = (XmlElement)sujetos.GetElementsByTagName("BuyerParty").Item(0);
            XmlNodeList nodosFacturas = facturas.GetElementsByTagName("Invoice");

            // VALIDACIONES DEL NODO CABECERA

            // Modalidad

            // Para la modalidad individual (I) el número de facturas debe ser 1
            String modalidad = ((XmlElement)cabecera.GetElementsByTagName("Modality").Item(0)).FirstChild.Value;
            String numFacturas = ((XmlElement)cabecera.GetElementsByTagName("InvoicesCount").Item(0)).FirstChild.Value;
            if (modalidad.Equals("I"))
            {
                if (Int16.Parse(numFacturas) != 1)
                {

                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityI));
                }
            }
            else
            {
                if (Int16.Parse(numFacturas) <= 1)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityL));
                }
            }

            // TipoEmisorFactura

            // Para TipoEmisorFactura TE debe existir el nodo Tercero 
            String tipoEmisorFactura = ((XmlElement)cabecera.GetElementsByTagName("InvoiceIssuerType").Item(0)).FirstChild.Value;
            if (tipoEmisorFactura.Equals("TE"))
            {
                XmlNodeList nlst = cabecera.GetElementsByTagName("ThirdParty");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceIssuerTypeTE));
                }
                else
                {
                    // Tercero	
                    // Correspondencia del tipo de persona con los datos
                    tercero = (XmlElement)nlst.Item(0);
                    String tipoDePersona = ((XmlElement)tercero.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;
                    if (tipoDePersona.Equals("F"))
                    {
                        nlst = tercero.GetElementsByTagName("Individual");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorPersonTypeCodeF));
                        }
                        else
                        {
                            XmlElement personaFisica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                    else
                    {
                        nlst = tercero.GetElementsByTagName("LegalEntity");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeJ));
                        }
                        else
                        {
                            XmlElement personaJuridica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                }
            }

            // Lote

            XmlElement totalFacturas = (XmlElement)lote.GetElementsByTagName("TotalInvoicesAmount").Item(0);
            XmlElement totalAPagar = (XmlElement)lote.GetElementsByTagName("TotalOutstandingAmount").Item(0);
            XmlElement totalAEjecutar = (XmlElement)lote.GetElementsByTagName("TotalExecutableAmount").Item(0);
            String moneda = ((XmlElement)lote.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;

            ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)
            
            //////if (moneda.Equals("EUR"))
            //////{
            //////    /*			// Si la moneda es euro, el ImporteTotal de TotalFacturas debe tener 2 decimales
            //////                String importe = ((Element)totalFacturas.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(8,"ImporteTotal de TotalFacturas no tiene 2 decimales");
            //////                }

            //////                // Si la moneda es euro, el ImporteTotal de TotalAPagar debe tener 2 decimales
            //////                importe = ((Element)totalAPagar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(9,"ImporteTotal de TotalAPagar no tiene 2 decimales");
            //////                }
    			
            //////                // Si la moneda es euro, el ImporteTotal de TotalAEjecutar debe tener 2 decimales
            //////                importe = ((Element)totalAEjecutar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(10,"ImporteTotal de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////    */
            //////}
            //////else
            //////{
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalFacturas
            //////    XmlNodeList nlst = totalFacturas.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalInvoicesAmountEquivalentInEuros));
            //////    }
            //////    // El número de decimales del cambio debe ser 2
            //////    /*			String tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(12,"TipoCambio de TotalFacturas no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                String importe = ((Element)totalFacturas.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(13,"ContravalorEuros de TotalFacturas no tiene 2 decimales");
            //////                }
    			
            //////    */
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalAPagar
            //////    nlst = totalAPagar.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmountEquivalentInEuros));
            //////    }
            //////    /*			// El número de decimales del cambio debe ser 2
            //////                tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(15,"TipoCambio de TotalAPagar no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                importe = ((Element)totalAPagar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(16,"ContravalorEuros de TotalAPagar no tiene 2 decimales");
            //////                }
    			
            //////    */
            //////    // Si la moneda no es euro, deben existir los datos del cambio para TotalAEjecutar
            //////    nlst = totalAEjecutar.GetElementsByTagName("EquivalentInEuros");
            //////    if (nlst.Count == 0)
            //////    {
            //////        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmountEquivalentInEuros));
            //////    }
            //////    /*			// El número de decimales del cambio debe ser 2
            //////                tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(tipo) != 2)
            //////                {
            //////                    throw new Exception(18,"TipoCambio de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////                // El número de decimales del contravalor en euros debe ser 2
            //////                importe = ((Element)totalAEjecutar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
            //////                if(decimales(importe) != 2)
            //////                {
            //////                    throw new Exception(19,"ContravalorEuros de TotalAEjecutar no tiene 2 decimales");
            //////                }
            //////    */
            //////}
            //Comprobamos que ImporteTotal de TotalFacturas, TotalAPagar y TotalAEjecutar coincide con la suma de los importes de cada factura
            String importeTotalFacturas = ((XmlElement)totalFacturas.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAPagar = ((XmlElement)totalAPagar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAEjecutar = ((XmlElement)totalAEjecutar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            if ((((Double.Parse(importeTotalFacturas)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAPagar)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAEjecutar)).CompareTo(0)) != 0))
            {
                double sumaTotalFacturas = 0;
                double sumaTotalAPagar = 0;
                double sumaTotalAEjecutar = 0;
                for (int i = 0; i < nodosFacturas.Count; i++)
                {
                    XmlElement factura = ((XmlElement)nodosFacturas.Item(i));
                    String totalFacturasInd = ((XmlElement)factura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                    sumaTotalFacturas += Double.Parse(totalFacturasInd);
                    String totalAPagarInd = ((XmlElement)factura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                    sumaTotalAPagar += Double.Parse(totalAPagarInd);
                    String totalAEjecutarInd = ((XmlElement)factura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                    sumaTotalAEjecutar += Double.Parse(totalAEjecutarInd);
                }
                if (((Double.Parse(importeTotalFacturas)).CompareTo(redondeo(sumaTotalFacturas))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountInvoiceTotal));
                }
                if (((Double.Parse(importeTotalAPagar)).CompareTo(redondeo(sumaTotalAPagar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalOutstandingAmount));
                }
                if (((Double.Parse(importeTotalAEjecutar)).CompareTo(redondeo(sumaTotalAEjecutar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalExecutableAmount));
                }
            }

            // DatosCesionFactoring

            // Correspondencia del tipo de persona con los datos
            XmlNodeList nl = cabecera.GetElementsByTagName("FactoringAssignmentData");
            if (nl.Count != 0)
            {
                datosCesionFactoring = (XmlElement)nl.Item(0);
                String tipoDePersona = ((XmlElement)datosCesionFactoring.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

                if (tipoDePersona.Equals("F"))
                {
                    nl = datosCesionFactoring.GetElementsByTagName("Individual");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeF));
                    }
                    else
                    {
                        XmlElement personaFisica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
                else
                {
                    nl = datosCesionFactoring.GetElementsByTagName("LegalEntity");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeJ));
                    }
                    else
                    {
                        XmlElement personaJuridica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
            }

            // VALIDACIONES DEL NODO SUJETOS

            // Emisor

            //comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = emisor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            // Correspondencia del tipo de persona con los datos
            String tipoPersona = ((XmlElement)emisor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = emisor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = emisor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Receptor

            //	comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = receptor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Correspondencia del tipo de persona con los datos
            tipoPersona = ((XmlElement)receptor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = receptor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = receptor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }


            // VALIDACIONES DEL NODO FACTURAS

            // Como puede haber mas de una factura las recorremos una a una haciendo todas las validaciones
            for (int i = 0; i < nodosFacturas.Count; i++)
            {
                XmlElement factura = ((XmlElement)nodosFacturas.Item(i));

                // Si la clase de factura es rectificativa, debe venir el nodo Rectificativa
                String clase = ((XmlElement)factura.GetElementsByTagName("InvoiceClass").Item(0)).FirstChild.Value;
                if (clase.Equals("OR") || clase.Equals("CR"))
                {
                    nl = factura.GetElementsByTagName("Corrective");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrective));
                    }
                    else
                    {
                        // Comprobamos que DescripcionCriterioRectificacion corresponde con el código elegido en CriterioRectificacion
                        XmlElement rectificaciva = (XmlElement)nl.Item(0);
                        String criterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethod").Item(0)).FirstChild.Value;
                        String decripcionCriterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethodDescription").Item(0)).FirstChild.Value;
                        //if (!(criterioRectificacion.Equals("01") && decripcionCriterioRectificacion.Equals("Rectificación íntegra")) &&
                        //        !(criterioRectificacion.Equals("02") && decripcionCriterioRectificacion.Equals("Rectificación por diferencias")))
                        //{
                        //    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrectionMethodDescription));
                        //}

                        //MODIFIQUE ESTE METODO PORQUE NO LE ENCONTRE LÓGICA YA QUE NUNCA SE CUMPLIRÍA

                        if (((decripcionCriterioRectificacion.Equals("Rectificación íntegra") || decripcionCriterioRectificacion.Equals("Full items")) && !criterioRectificacion.Equals("01")) || ((decripcionCriterioRectificacion.Equals("Rectificación por diferencias") || decripcionCriterioRectificacion.Equals("Corrected items only")) && !criterioRectificacion.Equals("02")) || ((decripcionCriterioRectificacion.Equals("Rectificación por descuento por volumen de operaciones durante un periodo") || decripcionCriterioRectificacion.Equals("Bulk deal in a given period")) && !criterioRectificacion.Equals("03")) || ((decripcionCriterioRectificacion.Equals("Autorizadas por la Agencia Tributaria") || decripcionCriterioRectificacion.Equals("Authorized by the Tax Agency")) && !criterioRectificacion.Equals("04")))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrectionMethodDescription));
                        }

                    }
                }
                //Si la clase es OC o CC, debe venir el nodo PeriodoFacturacion
                else if (clase.Equals("OC") || clase.Equals("CC"))
                {
                    nl = factura.GetElementsByTagName("InvoicingPeriod");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassInvoicingPeriod));
                    }
                }

                // MonedaImpuesto siempre debe ser EUR
                moneda = ((XmlElement)factura.GetElementsByTagName("TaxCurrencyCode").Item(0)).FirstChild.Value;
                //////if (!moneda.Equals("EUR"))
                //////{
                //////    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxCurrencyCode));
                //////}

                moneda = ((XmlElement)factura.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;



                // Totales factura

                XmlElement totalesFactura = (XmlElement)factura.GetElementsByTagName("InvoiceTotals").Item(0);

                // El número de decimales del TotalImporteBruto debe ser 2
                String totalImporteBruto = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmount").Item(0)).FirstChild.Value;
                double dTotalImporteBruto = Double.Parse(totalImporteBruto);
                /*			if(decimales(totalImporteBruto) != 2)
                            {
                                throw new Exception(61,"TotalImporteBruto de la factura no tiene 2 decimales");
                            }
                */


                // ImpuestosRepercutidos
                XmlElement impuestosRepercutidos = (XmlElement)factura.GetElementsByTagName("TaxesOutputs").Item(0);
                XmlNodeList nodosImpuestosRepercutidos = impuestosRepercutidos.GetElementsByTagName("Tax");
                XmlElement baseImponible = null;
                XmlElement cuota = null;
                double sumaImpuestosRepercutidos = 0;
                for (int j = 0; j < nodosImpuestosRepercutidos.Count; j++)
                {
                    XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidos.Item(j));
                    baseImponible = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                    cuota = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                    String importeBaseImponible = null;
                    String importeCuota = null;
                    String tipo = null;

                    // El número de decimales del PorcentajeImpuesto debe ser 2
                    XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                    String valorPorcentajeImpuesto = null;
                    if (porcentajeImpuesto != null)
                    {
                        valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                        if (decimales(valorPorcentajeImpuesto) != 2)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                        }
                    }


                    /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                    if (baseImponible != null)
                    {
                        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        /*						if(decimales(importeBaseImponible) != 2)
                                                {
                                                    throw new Exception(42,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                }
                        */
                        // La base imponible no puede superar el importe bruto
                        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBase));
                        }
                    }
                    if (cuota != null)
                    {
                        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        /*						if(decimales(importeCuota) != 2)
                                                {
                                                    throw new Exception(43,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                }
                        */
                    }


                    ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)

                    //////if (moneda.Equals("EUR"))
                    //////{
                    //////    if (baseImponible != null)
                    //////    {
                    //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                    //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeBaseImponible) != 2)
                    //////                                {
                    //////                                    throw new Exception(42,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // La base imponible no puede superar el importe bruto
                    //////        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBase));
                    //////        }
                    //////    }
                    //////    if (cuota != null)
                    //////    {
                    //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeCuota) != 2)
                    //////                                {
                    //////                                    throw new Exception(43,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////    }
                    //////}
                    //////else
                    //////{
                    //////    if (baseImponible != null)
                    //////    {
                    //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                    //////        nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                    //////        if (nl.Count == 0)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                    //////        }
                    //////        // El número de decimales del cambio debe ser 2
                    //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(tipo) != 2)
                    //////                                {
                    //////                                    throw new Exception(45,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // El número de decimales del contravalor en euros debe ser 2
                    //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeBaseImponible) != 2)
                    //////                                {
                    //////                                    throw new Exception(46,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }					
                    //////        */
                    //////    }
                    //////    if (cuota != null)
                    //////    {
                    //////        nl = cuota.GetElementsByTagName("EquivalentInEuros");
                    //////        if (nl.Count == 0)
                    //////        {
                    //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsTaxAmountEquivalentInEuros));
                    //////        }
                    //////        // El número de decimales del cambio debe ser 2
                    //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(tipo) != 2)
                    //////                                {
                    //////                                    throw new Exception(48,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////        // El número de decimales del contravalor en euros debe ser 2
                    //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                    //////        /*						if(decimales(importeCuota) != 2)
                    //////                                {
                    //////                                    throw new Exception(49,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                    //////                                }
                    //////        */
                    //////    }
                    //////}


                    // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                    if (cuota != null)
                    {
                        if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                        {
                            double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                            if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsPercent));
                            }
                        }

                        // Sumamos los importes de todas las cuotas para utilizarlos despues
                        sumaImpuestosRepercutidos += Double.Parse(importeCuota);
                    }
                }

                // ImpuestosRetenidos
                double sumaImpuestosRetenidos = 0;
                nl = factura.GetElementsByTagName("TaxesWithheld");
                if (nl.Count > 0)
                {
                    XmlElement impuestosRetenidos = (XmlElement)nl.Item(0);
                    XmlNodeList nodosImpuestosRetenidos = impuestosRetenidos.GetElementsByTagName("Tax");
                    for (int j = 0; j < nodosImpuestosRetenidos.Count; j++)
                    {
                        XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidos.Item(j));
                        baseImponible = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                        cuota = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                            }
                        }


                        /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                        if (baseImponible != null)
                        {
                            // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeBaseImponible) != 2)
                                                        {
                                                            throw new Exception(52,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                        }
                            */
                            // La base imponible no puede superar el importe bruto
                            if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseTotalAmount));
                            }
                        }
                        if (cuota != null)
                        {
                            importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeCuota) != 2)
                                                        {
                                                            throw new Exception(53,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                        }
                            */
                        }


                        ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)


                        //////if (moneda.Equals("EUR"))
                        //////{
                        //////    if (baseImponible != null)
                        //////    {
                        //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(52,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // La base imponible no puede superar el importe bruto
                        //////        if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseTotalAmount));
                        //////        }
                        //////    }
                        //////    if (cuota != null)
                        //////    {
                        //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(53,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}
                        //////else
                        //////{
                        //////    if (baseImponible != null)
                        //////    {
                        //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                        //////        nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(55,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(56,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }					
                        //////        */
                        //////    }
                        //////    if (cuota != null)
                        //////    {
                        //////        nl = cuota.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(58,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(59,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuota != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                }
                            }

                            // Sumamos los importes de todas las cuotas para utilizarlos despues
                            sumaImpuestosRetenidos += Double.Parse(importeCuota);
                        }
                    }
                }

                // Comprobacion del nodo DescuentosGenerales
                XmlElement descuentosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralDiscounts").Item(0);
                double sumaImportesDescuento = 0;
                if (descuentosGenerales != null)
                {
                    XmlNodeList nodosDescuentos = descuentosGenerales.GetElementsByTagName("Discount");
                    for (int k = 0; k < nodosDescuentos.Count; k++)
                    {
                        XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                        // El número de decimales del PorcentajeDescuento debe ser 4
                        XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                        if (porcentajeDescuento != null)
                        {
                            String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                            if (decimales(valorPorcentajeDescuento) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralDiscounts));
                            }
                        }
                        // El número de decimales del ImporteDescuento debe ser 2
                        String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeDescuento) != 2)
                                            {
                                                throw new Exception(63,"ImporteDescuento no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesDescuento += redondeo(Double.Parse(importeDescuento));
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo RecargosGenerales
                XmlElement recargosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralSurcharges").Item(0);
                double sumaImportesCargo = 0;
                if (recargosGenerales != null)
                {
                    XmlNodeList nodosRecargos = recargosGenerales.GetElementsByTagName("Charge");
                    for (int k = 0; k < nodosRecargos.Count; k++)
                    {
                        XmlElement cargo = ((XmlElement)nodosRecargos.Item(k));
                        // El número de decimales del PorcentajeCargo debe ser 4
                        XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                        if (porcentajeCargo != null)
                        {
                            String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                            if (decimales(valorPorcentajeCargo) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralSurcharges));
                            }
                        }
                        // El número de decimales del ImporteCargo debe ser 2
                        String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeCargo) != 2)
                                            {
                                                throw new Exception(65,"ImporteCargo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesCargo += Double.Parse(importeCargo);
                        /*					}
                        */
                    }
                }

                // El número de decimales del TotalDescuentosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteDescuento
                XmlElement totalDescuentosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralDiscounts").Item(0));
                if (totalDescuentosGenerales != null)
                {
                    String valorTotalDescuentosGenerales = totalDescuentosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalDescuentosGenerales) != 2)
                                    {
                                        throw new Exception(66,"TotalDescuentosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalDescuentosGenerales)).CompareTo(redondeo(sumaImportesDescuento))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralDiscounts));
                    }
                    /*				}
                    */
                }

                // El número de decimales del TotalCargosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteCargo
                XmlElement totalCargosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralSurcharges").Item(0));
                if (totalCargosGenerales != null)
                {
                    String valorTotalCargosGenerales = totalCargosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalCargosGenerales) != 2)
                                    {
                                        throw new Exception(68,"TotalCargosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalCargosGenerales)).CompareTo(redondeo(sumaImportesCargo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralSurcharges));
                    }
                    /*				}
                    */
                }

                //TotalImporteBrutoAntesImpuestos = TotalImporteBruto - TotalDescuentosGenerales + TotalCargosGenerales
                String totalImporteBrutoAntesImpuestos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmountBeforeTaxes").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImporteBrutoAntesImpuestos) != 2)
                            {
                                throw new Exception(70,"TotalImporteBrutoAntesImpuestos no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaImporteBrutoAntesImpuestos = Double.Parse(totalImporteBruto) - sumaImportesDescuento + sumaImportesCargo;
                if (((Double.Parse(totalImporteBrutoAntesImpuestos)).CompareTo(redondeo(sumaImporteBrutoAntesImpuestos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGrossAmountBeforeTaxes));
                }
                /*			}
                */
                // TotalImpuestosRepercutidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos repercutidos
                String totalImpuestosRepercutidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxOutputs").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImpuestosRepercutidos) != 2)
                            {
                                throw new Exception(72,"TotalImpuestosRepercutidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRepercutidos)).CompareTo(redondeo(sumaImpuestosRepercutidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxOutputs));
                }
                /*			}
                */
                // TotalImpuestosRetenidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos retenidos
                String totalImpuestosRetenidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxesWithheld").Item(0)).FirstChild.Value;
                /*			if(!totalImpuestosRetenidos.equals("0") && decimales(totalImpuestosRetenidos) != 2)
                            {
                                throw new Exception(74,"TotalImpuestosRetenidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRetenidos)).CompareTo(redondeo(sumaImpuestosRetenidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxesWithheld));
                }
                /*			}
                */
                // TotalFactura = TotalImporteBrutoAntesImpuestos + TotalImpuestosRepercutidos - TotalImpuestosRetenidos
                String totalfactura = ((XmlElement)totalesFactura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                /*			if(decimales(totalfactura) != 2)
                            {
                                throw new Exception(76,"Totalfactura no tiene 2 decimales");
                            }
                            else
                            {
                */
                double total = Double.Parse(totalImporteBrutoAntesImpuestos) + (Double.Parse(totalImpuestosRepercutidos) - Double.Parse(totalImpuestosRetenidos));
                if (((Double.Parse(totalfactura)).CompareTo(redondeo(total))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceTotal));
                }
                /*			}
                */
                // Comprobacion del nodo Subvenciones
                XmlElement subvenciones = (XmlElement)totalesFactura.GetElementsByTagName("Subsidies").Item(0);
                double sumaImportesSubvencion = 0;
                if (subvenciones != null)
                {
                    XmlNodeList nodosSubvenciones = subvenciones.GetElementsByTagName("Subsidy");
                    for (int j = 0; j < nodosSubvenciones.Count; j++)
                    {
                        XmlElement subvencion = ((XmlElement)nodosSubvenciones.Item(j));
                        // El número de decimales del PorcentajeSubvencion debe ser 4
                        XmlElement porcentajeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyRate").Item(0));
                        if (porcentajeSubvencion != null)
                        {
                            String valorPorcentajeSubvencion = porcentajeSubvencion.FirstChild.Value;
                            if (decimales(valorPorcentajeSubvencion) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSubsidyRate));
                            }
                        }
                        // El número de decimales del ImporteSubvencion debe ser 2
                        String importeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeSubvencion) != 2)
                                            {
                                                throw new Exception(79,"ImporteSubvencion no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesSubvencion += Double.Parse(importeSubvencion);
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo Anticipos
                XmlElement anticipos = (XmlElement)totalesFactura.GetElementsByTagName("PaymentsonAccount").Item(0);
                double sumaImportesAnticipo = 0;
                if (anticipos != null)
                {
                    XmlNodeList nodosAnticipos = anticipos.GetElementsByTagName("PaymentOnAccount");
                    for (int j = 0; j < nodosAnticipos.Count; j++)
                    {
                        XmlElement anticipo = ((XmlElement)nodosAnticipos.Item(j));
                        // El número de decimales del ImporteAnticipo debe ser 2
                        String importeAnticipo = ((XmlElement)anticipo.GetElementsByTagName("PaymentOnAccountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeAnticipo) != 2)
                                            {
                                                throw new Exception(80,"ImporteAnticipo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesAnticipo += Double.Parse(importeAnticipo);
                        /*					}
                        */
                    }
                }

                // TotalAnticipos debe coincidir con el sumatorio de los importes de los anticipos
                XmlElement totalAnticipos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalPaymentsOnAccount").Item(0));
                if (totalAnticipos != null)
                {
                    String valorTotalAnticipos = totalAnticipos.FirstChild.Value;
                    /*				if(decimales(valorTotalAnticipos) != 2)
                                    {
                                        throw new Exception(81,"TotalAnticipos no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalAnticipos)).CompareTo(redondeo(sumaImportesAnticipo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalPaymentsOnAccount));
                    }
                    /*				}
                    */
                }

                // TotalAPagar = TotalFactura - (Sumatorio de ImporteSubvencion + TotalAnticipos)
                String totalAPagarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAPagarFactura) != 2)
                            {
                                throw new Exception(83,"TotalAPagar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAPagarFactura = Double.Parse(totalfactura) - (sumaImportesSubvencion + sumaImportesAnticipo);
                if (((Double.Parse(totalAPagarFactura)).CompareTo(redondeo(sumaAPagarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmount));
                    /*				}
                    */
                }

                // Comprobacion del nodo RetencionGarantia
                XmlElement retencionGarantia = (XmlElement)totalesFactura.GetElementsByTagName("AmountsWithheld").Item(0);
                double valorImporteRetencion = 0;
                if (retencionGarantia != null)
                {
                    // El número de decimales del PorcentajeRetencion debe ser 4
                    XmlElement porcentajeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingRate").Item(0));
                    if (porcentajeRetencion != null)
                    {
                        String valorPorcentajeRetencion = porcentajeRetencion.FirstChild.Value;
                        if (decimales(valorPorcentajeRetencion) != 4)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorWithholdingRate));
                        }
                    }
                    // El número de decimales del ImporteRetencion debe ser 2
                    String importeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeRetencion) != 2)
                                    {
                                        throw new Exception(86,"ImporteRetencion no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    valorImporteRetencion = Double.Parse(importeRetencion);
                    /*				}
                    */
                }

                // TotalAEjecutar = TotalAPagar - ImporteRetencion
                String totalAEjecutarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAEjecutarFactura) != 2)
                            {
                                throw new Exception(87,"TotalAEjecutar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAEjecutarFactura = Double.Parse(totalAPagarFactura) - valorImporteRetencion;
                if (((Double.Parse(totalAEjecutarFactura)).CompareTo(redondeo(sumaAEjecutarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmount));
                }
                /*			}
                */
                // Detalles

                XmlElement detalles = ((XmlElement)factura.GetElementsByTagName("Items").Item(0));
                XmlNodeList nodosDetalles = detalles.GetElementsByTagName("InvoiceLine");
                double sumaImporteBruto = 0;
                for (int j = 0; j < nodosDetalles.Count; j++)
                {
                    XmlElement detalle = ((XmlElement)nodosDetalles.Item(j));

                    // El número de decimales del PrecioUnitarioSinImpuestos debe ser 2
                    String precioUnitarioSinImpuestos = ((XmlElement)detalle.GetElementsByTagName("UnitPriceWithoutTax").Item(0)).FirstChild.Value;
                    /*				if(decimales(precioUnitarioSinImpuestos) != 6)
                                    {
                                        throw new Exception(89,"PrecioUnitarioSinImpuestos no tiene 6 decimales");
                                    }
                    */
                    //Comprobar que CosteTotal = Cantidad * PrecioUnitarioSinImpuestos
                    String cantidad = ((XmlElement)detalle.GetElementsByTagName("Quantity").Item(0)).FirstChild.Value;
                    String costeTotal = ((XmlElement)detalle.GetElementsByTagName("TotalCost").Item(0)).FirstChild.Value;
                    /*				if(decimales(costeTotal) != 2)
                                    {
                                        throw new Exception(90,"CosteTotal no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double sumaCosteTotal = Double.Parse(precioUnitarioSinImpuestos) * Double.Parse(cantidad);
                    if (((redondeo(Double.Parse(costeTotal))).CompareTo(redondeo(sumaCosteTotal))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalCost));
                    }
                    /*				}
                    */
                    // Comprobacion del nodo Descuentos
                    XmlElement descuentos = (XmlElement)detalle.GetElementsByTagName("DiscountsAndRebates").Item(0);
                    double sumaImportesDescuentoDetalle = 0;
                    if (descuentos != null)
                    {
                        XmlNodeList nodosDescuentos = descuentos.GetElementsByTagName("Discount");
                        for (int k = 0; k < nodosDescuentos.Count; k++)
                        {
                            XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                            // El número de decimales del PorcentajeDescuento debe ser 4
                            XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                            if (porcentajeDescuento != null)
                            {
                                String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                                if (decimales(valorPorcentajeDescuento) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorDiscountRate));
                                }
                            }
                            // El número de decimales del ImporteDescuento debe ser 2
                            String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeDescuento) != 2)
                                                    {
                                                        throw new Exception(93,"ImporteDescuento no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesDescuentoDetalle += redondeo(Double.Parse(importeDescuento));
                            /*						}
                            */
                        }
                    }

                    // Comprobacion del nodo Cargos
                    XmlElement cargos = (XmlElement)detalle.GetElementsByTagName("Charges").Item(0);
                    double sumaImportesCargoDetalle = 0;
                    if (cargos != null)
                    {
                        XmlNodeList nodosCargos = cargos.GetElementsByTagName("Charge");
                        for (int k = 0; k < nodosCargos.Count; k++)
                        {
                            XmlElement cargo = ((XmlElement)nodosCargos.Item(k));
                            // El número de decimales del PorcentajeCargo debe ser 4
                            XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                            if (porcentajeCargo != null)
                            {
                                String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                                if (decimales(valorPorcentajeCargo) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorChargeRate));
                                }
                            }
                            // El número de decimales del ImporteCargo debe ser 2
                            String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeCargo) != 2)
                                                    {
                                                        throw new Exception(95,"ImporteCargo no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesCargoDetalle += Double.Parse(importeCargo);
                            /*						}
                            */
                        }
                    }

                    // Comprobar que ImporteBruto = CosteTotal - Sumatorio de ImporteDescuento + Sumatorio de ImporteCargo
                    String importeBruto = ((XmlElement)detalle.GetElementsByTagName("GrossAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeBruto) != 2)
                                    {
                                        throw new Exception(96,"ImporteBruto no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double suma = redondeo(Double.Parse(costeTotal)) - sumaImportesDescuentoDetalle + sumaImportesCargoDetalle;
                    if (((redondeo(Double.Parse(importeBruto))).CompareTo(redondeo(suma))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGrossAmount));
                    }
                    else
                    {
                        sumaImporteBruto += redondeo(Double.Parse(importeBruto));
                    }
                    /*				}
                    */
                    // ImpuestosRetenidos
                    XmlElement baseImponibleDetalle = null;
                    XmlElement cuotaDetalle = null;
                    nl = detalle.GetElementsByTagName("TaxesWithheld");
                    if (nl.Count > 0)
                    {
                        XmlElement impuestosRetenidosDetalle = (XmlElement)nl.Item(0);
                        XmlNodeList nodosImpuestosRetenidosDetalle = impuestosRetenidosDetalle.GetElementsByTagName("Tax");
                        for (int k = 0; k < nodosImpuestosRetenidosDetalle.Count; k++)
                        {
                            XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidosDetalle.Item(k));
                            baseImponibleDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                            cuotaDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                            String importeBaseImponible = null;
                            String importeCuota = null;
                            String tipo = null;

                            // El número de decimales del PorcentajeImpuesto debe ser 2
                            XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                            String valorPorcentajeImpuesto = null;
                            if (porcentajeImpuesto != null)
                            {
                                valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                                if (decimales(valorPorcentajeImpuesto) != 2)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                                }
                            }


                            /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                            if (baseImponibleDetalle != null)
                            {
                                // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                                importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*								if(decimales(importeBaseImponible) != 2)
                                                                {
                                                                    throw new Exception(109,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                                }
                                */
                            }
                            if (cuotaDetalle != null)
                            {
                                importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*								if(decimales(importeCuota) != 2)
                                                                {
                                                                    throw new Exception(110,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                                }
                                */
                            }


                            ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)
                            
                            
                            //////if (moneda.Equals("EUR"))
                            //////{
                            //////    if (baseImponibleDetalle != null)
                            //////    {
                            //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeBaseImponible) != 2)
                            //////                                        {
                            //////                                            throw new Exception(109,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////    if (cuotaDetalle != null)
                            //////    {
                            //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeCuota) != 2)
                            //////                                        {
                            //////                                            throw new Exception(110,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////}
                            //////else
                            //////{
                            //////    if (baseImponibleDetalle != null)
                            //////    {
                            //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                            //////        nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                            //////        if (nl.Count == 0)
                            //////        {
                            //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                            //////        }
                            //////        // El número de decimales del cambio debe ser 2
                            //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(tipo) != 2)
                            //////                                        {
                            //////                                            throw new Exception(112,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////        // El número de decimales del contravalor en euros debe ser 2
                            //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeBaseImponible) != 2)
                            //////                                        {
                            //////                                            throw new Exception(113,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }					
                            //////        */
                            //////    }
                            //////    if (cuotaDetalle != null)
                            //////    {
                            //////        nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                            //////        if (nl.Count == 0)
                            //////        {
                            //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                            //////        }
                            //////        // El número de decimales del cambio debe ser 2
                            //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(tipo) != 2)
                            //////                                        {
                            //////                                            throw new Exception(115,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////        // El número de decimales del contravalor en euros debe ser 2
                            //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            //////        /*								if(decimales(importeCuota) != 2)
                            //////                                        {
                            //////                                            throw new Exception(116,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                            //////                                        }
                            //////        */
                            //////    }
                            //////}

                            // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                            if (cuotaDetalle != null)
                            {
                                if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                                {
                                    double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                    if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                    }
                                }
                            }
                        }
                    }

                    // ImpuestosRepercutidos
                    XmlElement impuestosRepercutidosDetalle = (XmlElement)detalle.GetElementsByTagName("TaxesOutputs").Item(0);
                    XmlNodeList nodosImpuestosRepercutidosDetalle = impuestosRepercutidosDetalle.GetElementsByTagName("Tax");
                    for (int k = 0; k < nodosImpuestosRepercutidosDetalle.Count; k++)
                    {
                        XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidosDetalle.Item(k));
                        baseImponibleDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                        cuotaDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                            }
                        }


                        /************* CODIGO AUXILIAR HASTA SOLUCION ***************/


                        if (baseImponibleDetalle != null)
                        {
                            // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeBaseImponible) != 2)
                                                        {
                                                            throw new Exception(99,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                        }
                            */
                        }
                        if (cuotaDetalle != null)
                        {
                            importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*							if(decimales(importeCuota) != 2)
                                                        {
                                                            throw new Exception(100,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                        }
                            */
                        }


                        ////// 3 COMENTARIOS PARA ERROR DE MONEDA (ERROR EURO)


                        //////if (moneda.Equals("EUR"))
                        //////{
                        //////    if (baseImponibleDetalle != null)
                        //////    {
                        //////        // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                        //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(99,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////    if (cuotaDetalle != null)
                        //////    {
                        //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(100,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}
                        //////else
                        //////{
                        //////    if (baseImponibleDetalle != null)
                        //////    {
                        //////        // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                        //////        nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(102,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeBaseImponible) != 2)
                        //////                                    {
                        //////                                        throw new Exception(103,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }					
                        //////        */
                        //////    }
                        //////    if (cuotaDetalle != null)
                        //////    {
                        //////        nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                        //////        if (nl.Count == 0)
                        //////        {
                        //////            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                        //////        }
                        //////        // El número de decimales del cambio debe ser 2
                        //////        tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(tipo) != 2)
                        //////                                    {
                        //////                                        throw new Exception(105,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////        // El número de decimales del contravalor en euros debe ser 2
                        //////        importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                        //////        /*							if(decimales(importeCuota) != 2)
                        //////                                    {
                        //////                                        throw new Exception(106,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                        //////                                    }
                        //////        */
                        //////    }
                        //////}

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuotaDetalle != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                }
                            }
                        }

                    }
                }

                // Comprobar que la suma de los importes brutos de los detalles coincide con el total
                if (((Double.Parse(totalImporteBruto)).CompareTo(redondeo(sumaImporteBruto))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSumGrossAmount));
                }

                // DatosCobro

                nl = factura.GetElementsByTagName("PaymentDetails");
                if (nl.Count > 0)
                {
                    XmlElement datosCobro = (XmlElement)nl.Item(0);
                    XmlNodeList nodosVencimiento = datosCobro.GetElementsByTagName("Installment");
                    for (int j = 0; j < nodosVencimiento.Count; j++)
                    {
                        XmlElement vencimiento = ((XmlElement)nodosVencimiento.Item(j));

                        // El número de decimales del ImporteVencimiento debe ser 2
                        String importeVencimiento = ((XmlElement)vencimiento.GetElementsByTagName("InstallmentAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeVencimiento) != 2)
                                            {
                                                throw new Exception(119,"ImporteVencimiento no tiene 2 decimales");
                                            }
                        */
                        // Si FormaPago es "Trasferencia", el nodo CuentaAbono es obligatorio
                        String formaPago = ((XmlElement)vencimiento.GetElementsByTagName("PaymentMeans").Item(0)).FirstChild.Value;
                        if (formaPago.Equals("Transferencia"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeCredited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeCredited));
                            }
                            else
                            {
                                XmlElement cuentaAbono = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaAbono.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                        // Si FormaPago es "Recibo", el nodo CuentaCargo es obligatorio
                        else if (formaPago.Equals("Recibo"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeDebited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeDebited));
                            }
                            else
                            {
                                XmlElement cuentaCargo = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaCargo.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Validación contable de Facturae v3.0
        /// </summary>
        /// <param name="doc">Documento xml con la facturae</param>
        public static void ValidationAccountingV30(XmlDocument doc)
        {
            ControlMessages msg = ControlMessages.getInstance();
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            // Recuperamos el nodo inicial de la factura (el documento podría venir incluido
            // en otro, como un documento SOAP por ejemplo)

            XmlElement raiz = (XmlElement)doc.DocumentElement;

            // Bloques
            XmlElement cabecera = (XmlElement)raiz.GetElementsByTagName("FileHeader").Item(0);
            XmlElement sujetos = (XmlElement)raiz.GetElementsByTagName("Parties").Item(0);
            XmlElement facturas = (XmlElement)raiz.GetElementsByTagName("Invoices").Item(0);

            // Nivel 1
            XmlElement tercero = null;
            XmlElement datosCesionFactoring = null;
            XmlElement lote = (XmlElement)cabecera.GetElementsByTagName("Batch").Item(0);
            XmlElement emisor = (XmlElement)sujetos.GetElementsByTagName("SellerParty").Item(0);
            XmlElement receptor = (XmlElement)sujetos.GetElementsByTagName("BuyerParty").Item(0);
            XmlNodeList nodosFacturas = facturas.GetElementsByTagName("Invoice");

            // VALIDACIONES DEL NODO CABECERA

            // Modalidad

            // Para la modalidad individual (I) el número de facturas debe ser 1
            String modalidad = ((XmlElement)cabecera.GetElementsByTagName("Modality").Item(0)).FirstChild.Value;
            String numFacturas = ((XmlElement)cabecera.GetElementsByTagName("InvoicesCount").Item(0)).FirstChild.Value;
            if (modalidad.Equals("I"))
            {
                if (Int16.Parse(numFacturas) != 1)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityI));
                }
            }
            else
            {
                if (Int16.Parse(numFacturas) <= 1)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorModalityL));
                }
            }

            // TipoEmisorFactura

            // Para TipoEmisorFactura TE debe existir el nodo Tercero 
            String tipoEmisorFactura = ((XmlElement)cabecera.GetElementsByTagName("InvoiceIssuerType").Item(0)).FirstChild.Value;
            if (tipoEmisorFactura.Equals("TE"))
            {
                XmlNodeList nlst = cabecera.GetElementsByTagName("ThirdParty");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceIssuerTypeTE));
                }
                else
                {
                    // Tercero	
                    // Correspondencia del tipo de persona con los datos
                    tercero = (XmlElement)nlst.Item(0);
                    String tipoDePersona = ((XmlElement)tercero.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;
                    if (tipoDePersona.Equals("F"))
                    {
                        nlst = tercero.GetElementsByTagName("Individual");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorPersonTypeCodeF));
                        }
                        else
                        {
                            XmlElement personaFisica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                    else
                    {
                        nlst = tercero.GetElementsByTagName("LegalEntity");
                        if (nlst.Count == 0)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorPersonTypeCodeJ));
                        }
                        else
                        {
                            XmlElement personaJuridica = (XmlElement)nlst.Item(0);
                            XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                            //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                            if (direccionNacional != null)
                            {
                                String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                if (!codigoPais.Equals("ESP"))
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                }
                            }
                        }
                    }
                }
            }

            // Lote

            XmlElement totalFacturas = (XmlElement)lote.GetElementsByTagName("TotalInvoicesAmount").Item(0);
            XmlElement totalAPagar = (XmlElement)lote.GetElementsByTagName("TotalOutstandingAmount").Item(0);
            XmlElement totalAEjecutar = (XmlElement)lote.GetElementsByTagName("TotalExecutableAmount").Item(0);
            String moneda = ((XmlElement)lote.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;
            if (moneda.Equals("EUR"))
            {
                /*			// Si la moneda es euro, el ImporteTotal de TotalFacturas debe tener 2 decimales
                            String importe = ((Element)totalFacturas.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(8,"ImporteTotal de TotalFacturas no tiene 2 decimales");
                            }

                            // Si la moneda es euro, el ImporteTotal de TotalAPagar debe tener 2 decimales
                            importe = ((Element)totalAPagar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(9,"ImporteTotal de TotalAPagar no tiene 2 decimales");
                            }
				
                            // Si la moneda es euro, el ImporteTotal de TotalAEjecutar debe tener 2 decimales
                            importe = ((Element)totalAEjecutar.getElementsByTagName("TotalAmount").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(10,"ImporteTotal de TotalAEjecutar no tiene 2 decimales");
                            }
                */
            }
            else
            {
                // Si la moneda no es euro, deben existir los datos del cambio para TotalFacturas
                XmlNodeList nlst = totalFacturas.GetElementsByTagName("EquivalentInEuros");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalInvoicesAmountEquivalentInEuros));
                }
                // El número de decimales del cambio debe ser 2
                /*			String tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
                            if(decimales(tipo) != 2)
                            {
                                throw new Exception(12,"TipoCambio de TotalFacturas no tiene 2 decimales");
                            }
                            // El número de decimales del contravalor en euros debe ser 2
                            String importe = ((Element)totalFacturas.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(13,"ContravalorEuros de TotalFacturas no tiene 2 decimales");
                            }
				
                */
                // Si la moneda no es euro, deben existir los datos del cambio para TotalAPagar
                nlst = totalAPagar.GetElementsByTagName("EquivalentInEuros");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmountEquivalentInEuros));
                }
                /*			// El número de decimales del cambio debe ser 2
                            tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
                            if(decimales(tipo) != 2)
                            {
                                throw new Exception(15,"TipoCambio de TotalAPagar no tiene 2 decimales");
                            }
                            // El número de decimales del contravalor en euros debe ser 2
                            importe = ((Element)totalAPagar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(16,"ContravalorEuros de TotalAPagar no tiene 2 decimales");
                            }
				
                */
                // Si la moneda no es euro, deben existir los datos del cambio para TotalAEjecutar
                nlst = totalAEjecutar.GetElementsByTagName("EquivalentInEuros");
                if (nlst.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmountEquivalentInEuros));
                }
                /*			// El número de decimales del cambio debe ser 2
                            tipo = ((Element)nl.item(0)).getFirstChild().getNodeValue();
                            if(decimales(tipo) != 2)
                            {
                                throw new Exception(18,"TipoCambio de TotalAEjecutar no tiene 2 decimales");
                            }
                            // El número de decimales del contravalor en euros debe ser 2
                            importe = ((Element)totalAEjecutar.getElementsByTagName("EquivalentInEuros").item(0)).getFirstChild().getNodeValue();
                            if(decimales(importe) != 2)
                            {
                                throw new Exception(19,"ContravalorEuros de TotalAEjecutar no tiene 2 decimales");
                            }
                */
            }
            //Comprobamos que ImporteTotal de TotalFacturas, TotalAPagar y TotalAEjecutar coincide con la suma de los importes de cada factura
            String importeTotalFacturas = ((XmlElement)totalFacturas.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAPagar = ((XmlElement)totalAPagar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            String importeTotalAEjecutar = ((XmlElement)totalAEjecutar.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
            if ((((Double.Parse(importeTotalFacturas)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAPagar)).CompareTo(0)) != 0) ||
                    (((Double.Parse(importeTotalAEjecutar)).CompareTo(0)) != 0))
            {
                double sumaTotalFacturas = 0;
                double sumaTotalAPagar = 0;
                double sumaTotalAEjecutar = 0;
                for (int i = 0; i < nodosFacturas.Count; i++)
                {
                    XmlElement factura = ((XmlElement)nodosFacturas.Item(i));
                    String totalFacturasInd = ((XmlElement)factura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                    sumaTotalFacturas += Double.Parse(totalFacturasInd);
                    String totalAPagarInd = ((XmlElement)factura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                    sumaTotalAPagar += Double.Parse(totalAPagarInd);
                    String totalAEjecutarInd = ((XmlElement)factura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                    sumaTotalAEjecutar += Double.Parse(totalAEjecutarInd);
                }
                if (((Double.Parse(importeTotalFacturas)).CompareTo(redondeo(sumaTotalFacturas))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountInvoiceTotal));
                }
                if (((Double.Parse(importeTotalAPagar)).CompareTo(redondeo(sumaTotalAPagar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalOutstandingAmount));
                }
                if (((Double.Parse(importeTotalAEjecutar)).CompareTo(redondeo(sumaTotalAEjecutar))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalAmountTotalExecutableAmount));
                }
            }

            // DatosCesionFactoring

            // Correspondencia del tipo de persona con los datos
            XmlNodeList nl = cabecera.GetElementsByTagName("FactoringAssignmentData");
            if (nl.Count != 0)
            {
                datosCesionFactoring = (XmlElement)nl.Item(0);
                String tipoDePersona = ((XmlElement)datosCesionFactoring.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

                if (tipoDePersona.Equals("F"))
                {
                    nl = datosCesionFactoring.GetElementsByTagName("Individual");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeF));
                    }
                    else
                    {
                        XmlElement personaFisica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
                else
                {
                    nl = datosCesionFactoring.GetElementsByTagName("LegalEntity");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorFactoringAssignmentDataPersonTypeCodeJ));
                    }
                    else
                    {
                        XmlElement personaJuridica = (XmlElement)nl.Item(0);
                        XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                        //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                        if (direccionNacional != null)
                        {
                            String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                            if (!codigoPais.Equals("ESP"))
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                            }
                        }
                    }
                }
            }

            // VALIDACIONES DEL NODO SUJETOS

            // Emisor

            //comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = emisor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Correspondencia del tipo de persona con los datos
            String tipoPersona = ((XmlElement)emisor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = emisor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = emisor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorIssuerTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Receptor

            //	comprobamos que si existe el nodo Centros, si se ha elegido direccionNacional el codigoPais sea ESP
            nl = receptor.GetElementsByTagName("AdministrativeCentres");
            if (nl.Count > 0)
            {
                XmlElement centros = (XmlElement)nl.Item(0);
                XmlNodeList nodosCentros = centros.GetElementsByTagName("AdministrativeCentre");
                for (int i = 0; i < nodosCentros.Count; i++)
                {
                    XmlElement centro = ((XmlElement)nodosCentros.Item(i));
                    XmlElement direccionNacional = ((XmlElement)centro.GetElementsByTagName("AddressInSpain").Item(0));
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }

            // Correspondencia del tipo de persona con los datos
            tipoPersona = ((XmlElement)receptor.GetElementsByTagName("PersonTypeCode").Item(0)).FirstChild.Value;

            if (tipoPersona.Equals("F"))
            {
                nl = receptor.GetElementsByTagName("Individual");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeF));
                }
                else
                {
                    XmlElement personaFisica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaFisica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }
            else
            {
                nl = receptor.GetElementsByTagName("LegalEntity");
                if (nl.Count == 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorReciverTypeCodeJ));
                }
                else
                {
                    XmlElement personaJuridica = (XmlElement)nl.Item(0);
                    XmlElement direccionNacional = ((XmlElement)personaJuridica.GetElementsByTagName("AddressInSpain").Item(0));
                    //comprobamos que si se ha elegido direccionNacional el codigoPais es ESP
                    if (direccionNacional != null)
                    {
                        String codigoPais = ((XmlElement)direccionNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                        if (!codigoPais.Equals("ESP"))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                        }
                    }
                }
            }


            // VALIDACIONES DEL NODO FACTURAS

            // Como puede haber mas de una factura las recorremos una a una haciendo todas las validaciones
            for (int i = 0; i < nodosFacturas.Count; i++)
            {
                XmlElement factura = ((XmlElement)nodosFacturas.Item(i));

                // Si la clase de factura es rectificativa, debe venir el nodo Rectificativa
                String clase = ((XmlElement)factura.GetElementsByTagName("InvoiceClass").Item(0)).FirstChild.Value;
                if (clase.Equals("OR") || clase.Equals("CR"))
                {
                    nl = factura.GetElementsByTagName("Corrective");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrective));
                    }
                    else
                    {
                        // Comprobamos que DescripcionCriterioRectificacion corresponde con el código elegido en CriterioRectificacion
                        XmlElement rectificaciva = (XmlElement)nl.Item(0);
                        String criterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethod").Item(0)).FirstChild.Value;
                        String decripcionCriterioRectificacion = ((XmlElement)rectificaciva.GetElementsByTagName("CorrectionMethodDescription").Item(0)).FirstChild.Value;
                        if (!(criterioRectificacion.Equals("01") && decripcionCriterioRectificacion.Equals("Rectificación íntegra")) &&
                                !(criterioRectificacion.Equals("02") && decripcionCriterioRectificacion.Equals("Rectificación por diferencias")))
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassCorrectionMethodDescription));
                        }
                    }
                }
                //Si la clase es OC o CC, debe venir el nodo PeriodoFacturacion
                else if (clase.Equals("OC") || clase.Equals("CC"))
                {
                    nl = factura.GetElementsByTagName("InvoicingPeriod");
                    if (nl.Count == 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceClassInvoicingPeriod));
                    }
                }

                // MonedaImpuesto siempre debe ser EUR
                moneda = ((XmlElement)factura.GetElementsByTagName("TaxCurrencyCode").Item(0)).FirstChild.Value;
                if (!moneda.Equals("EUR"))
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxCurrencyCode));
                }

                moneda = ((XmlElement)factura.GetElementsByTagName("InvoiceCurrencyCode").Item(0)).FirstChild.Value;



                // Totales factura

                XmlElement totalesFactura = (XmlElement)factura.GetElementsByTagName("InvoiceTotals").Item(0);

                // El número de decimales del TotalImporteBruto debe ser 2
                String totalImporteBruto = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmount").Item(0)).FirstChild.Value;
                double dTotalImporteBruto = Double.Parse(totalImporteBruto);
                /*			if(decimales(totalImporteBruto) != 2)
                            {
                                throw new Exception(61,"TotalImporteBruto de la factura no tiene 2 decimales");
                            }
                */


                // ImpuestosRepercutidos
                XmlElement impuestosRepercutidos = (XmlElement)factura.GetElementsByTagName("TaxesOutputs").Item(0);
                XmlNodeList nodosImpuestosRepercutidos = impuestosRepercutidos.GetElementsByTagName("Tax");
                XmlElement baseImponible = null;
                XmlElement cuota = null;
                double sumaImpuestosRepercutidos = 0;
                for (int j = 0; j < nodosImpuestosRepercutidos.Count; j++)
                {
                    XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidos.Item(j));
                    baseImponible = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                    cuota = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                    String importeBaseImponible = null;
                    String importeCuota = null;
                    String tipo = null;

                    // El número de decimales del PorcentajeImpuesto debe ser 2
                    XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                    String valorPorcentajeImpuesto = null;
                    if (porcentajeImpuesto != null)
                    {
                        valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                        if (decimales(valorPorcentajeImpuesto) != 2)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                        }
                    }

                    if (moneda.Equals("EUR"))
                    {
                        if (baseImponible != null)
                        {
                            // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                            importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeBaseImponible) != 2)
                                                    {
                                                        throw new Exception(42,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }
                            */
                            // La base imponible no puede superar el importe bruto
                            if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBase));
                            }
                        }
                        if (cuota != null)
                        {
                            importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeCuota) != 2)
                                                    {
                                                        throw new Exception(43,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }
                            */
                        }
                    }
                    else
                    {
                        if (baseImponible != null)
                        {
                            // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                            nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                            }
                            // El número de decimales del cambio debe ser 2
                            tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            /*						if(decimales(tipo) != 2)
                                                    {
                                                        throw new Exception(45,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }
                            */
                            // El número de decimales del contravalor en euros debe ser 2
                            importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeBaseImponible) != 2)
                                                    {
                                                        throw new Exception(46,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }					
                            */
                        }
                        if (cuota != null)
                        {
                            nl = cuota.GetElementsByTagName("EquivalentInEuros");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsTaxAmountEquivalentInEuros));
                            }
                            // El número de decimales del cambio debe ser 2
                            tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                            /*						if(decimales(tipo) != 2)
                                                    {
                                                        throw new Exception(48,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }
                            */
                            // El número de decimales del contravalor en euros debe ser 2
                            importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeCuota) != 2)
                                                    {
                                                        throw new Exception(49,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                    }
                            */
                        }
                    }


                    // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                    if (cuota != null)
                    {
                        if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                        {
                            double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                            if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsPercent));
                            }
                        }

                        // Sumamos los importes de todas las cuotas para utilizarlos despues
                        sumaImpuestosRepercutidos += Double.Parse(importeCuota);
                    }
                }

                // ImpuestosRetenidos
                double sumaImpuestosRetenidos = 0;
                nl = factura.GetElementsByTagName("TaxesWithheld");
                if (nl.Count > 0)
                {
                    XmlElement impuestosRetenidos = (XmlElement)nl.Item(0);
                    XmlNodeList nodosImpuestosRetenidos = impuestosRetenidos.GetElementsByTagName("Tax");
                    for (int j = 0; j < nodosImpuestosRetenidos.Count; j++)
                    {
                        XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidos.Item(j));
                        baseImponible = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                        cuota = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                            }
                        }

                        if (moneda.Equals("EUR"))
                        {
                            if (baseImponible != null)
                            {
                                // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                                importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeBaseImponible) != 2)
                                                            {
                                                                throw new Exception(52,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                            }
                                */
                                // La base imponible no puede superar el importe bruto
                                if (Double.Parse(importeBaseImponible) > dTotalImporteBruto)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseTotalAmount));
                                }
                            }
                            if (cuota != null)
                            {
                                importeCuota = ((XmlElement)cuota.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeCuota) != 2)
                                                            {
                                                                throw new Exception(53,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                            }
                                */
                            }
                        }
                        else
                        {
                            if (baseImponible != null)
                            {
                                // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                                nl = baseImponible.GetElementsByTagName("EquivalentInEuros");
                                if (nl.Count == 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                                }
                                // El número de decimales del cambio debe ser 2
                                tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                /*							if(decimales(tipo) != 2)
                                                            {
                                                                throw new Exception(55,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                            }
                                */
                                // El número de decimales del contravalor en euros debe ser 2
                                importeBaseImponible = ((XmlElement)baseImponible.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeBaseImponible) != 2)
                                                            {
                                                                throw new Exception(56,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                            }					
                                */
                            }
                            if (cuota != null)
                            {
                                nl = cuota.GetElementsByTagName("EquivalentInEuros");
                                if (nl.Count == 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                                }
                                // El número de decimales del cambio debe ser 2
                                tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                /*							if(decimales(tipo) != 2)
                                                            {
                                                                throw new Exception(58,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                            }
                                */
                                // El número de decimales del contravalor en euros debe ser 2
                                importeCuota = ((XmlElement)cuota.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeCuota) != 2)
                                                            {
                                                                throw new Exception(59,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                            }
                                */
                            }
                        }

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuota != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                }
                            }

                            // Sumamos los importes de todas las cuotas para utilizarlos despues
                            sumaImpuestosRetenidos += Double.Parse(importeCuota);
                        }
                    }
                }

                // Comprobacion del nodo DescuentosGenerales
                XmlElement descuentosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralDiscounts").Item(0);
                double sumaImportesDescuento = 0;
                if (descuentosGenerales != null)
                {
                    XmlNodeList nodosDescuentos = descuentosGenerales.GetElementsByTagName("Discount");
                    for (int k = 0; k < nodosDescuentos.Count; k++)
                    {
                        XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                        // El número de decimales del PorcentajeDescuento debe ser 4
                        XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                        if (porcentajeDescuento != null)
                        {
                            String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                            if (decimales(valorPorcentajeDescuento) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralDiscounts));
                            }
                        }
                        // El número de decimales del ImporteDescuento debe ser 2
                        String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeDescuento) != 2)
                                            {
                                                throw new Exception(63,"ImporteDescuento no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesDescuento += Double.Parse(importeDescuento);
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo RecargosGenerales
                XmlElement recargosGenerales = (XmlElement)totalesFactura.GetElementsByTagName("GeneralSurcharges").Item(0);
                double sumaImportesCargo = 0;
                if (recargosGenerales != null)
                {
                    XmlNodeList nodosRecargos = recargosGenerales.GetElementsByTagName("Charge");
                    for (int k = 0; k < nodosRecargos.Count; k++)
                    {
                        XmlElement cargo = ((XmlElement)nodosRecargos.Item(k));
                        // El número de decimales del PorcentajeCargo debe ser 4
                        XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                        if (porcentajeCargo != null)
                        {
                            String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                            if (decimales(valorPorcentajeCargo) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGeneralSurcharges));
                            }
                        }
                        // El número de decimales del ImporteCargo debe ser 2
                        String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeCargo) != 2)
                                            {
                                                throw new Exception(65,"ImporteCargo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesCargo += Double.Parse(importeCargo);
                        /*					}
                        */
                    }
                }

                // El número de decimales del TotalDescuentosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteDescuento
                XmlElement totalDescuentosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralDiscounts").Item(0));
                if (totalDescuentosGenerales != null)
                {
                    String valorTotalDescuentosGenerales = totalDescuentosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalDescuentosGenerales) != 2)
                                    {
                                        throw new Exception(66,"TotalDescuentosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalDescuentosGenerales)).CompareTo(redondeo(sumaImportesDescuento))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralDiscounts));
                    }
                    /*				}
                    */
                }

                // El número de decimales del TotalCargosGenerales debe ser 2 y además debe coincidir con el sumatorio de todos los ImporteCargo
                XmlElement totalCargosGenerales = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGeneralSurcharges").Item(0));
                if (totalCargosGenerales != null)
                {
                    String valorTotalCargosGenerales = totalCargosGenerales.FirstChild.Value;
                    /*				if(decimales(valorTotalCargosGenerales) != 2)
                                    {
                                        throw new Exception(68,"TotalCargosGenerales no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalCargosGenerales)).CompareTo(redondeo(sumaImportesCargo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGeneralSurcharges));
                    }
                    /*				}
                    */
                }

                //TotalImporteBrutoAntesImpuestos = TotalImporteBruto - TotalDescuentosGenerales + TotalCargosGenerales
                String totalImporteBrutoAntesImpuestos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalGrossAmountBeforeTaxes").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImporteBrutoAntesImpuestos) != 2)
                            {
                                throw new Exception(70,"TotalImporteBrutoAntesImpuestos no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaImporteBrutoAntesImpuestos = Double.Parse(totalImporteBruto) - sumaImportesDescuento + sumaImportesCargo;
                if (((Double.Parse(totalImporteBrutoAntesImpuestos)).CompareTo(redondeo(sumaImporteBrutoAntesImpuestos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalGrossAmountBeforeTaxes));
                }
                /*			}
                */
                // TotalImpuestosRepercutidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos repercutidos
                String totalImpuestosRepercutidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxOutputs").Item(0)).FirstChild.Value;
                /*			if(decimales(totalImpuestosRepercutidos) != 2)
                            {
                                throw new Exception(72,"TotalImpuestosRepercutidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRepercutidos)).CompareTo(redondeo(sumaImpuestosRepercutidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxOutputs));
                }
                /*			}
                */
                // TotalImpuestosRetenidos debe coincidir con el sumatorio de los importes totales de las cuotas de los impuestos retenidos
                String totalImpuestosRetenidos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalTaxesWithheld").Item(0)).FirstChild.Value;
                /*			if(!totalImpuestosRetenidos.equals("0") && decimales(totalImpuestosRetenidos) != 2)
                            {
                                throw new Exception(74,"TotalImpuestosRetenidos no tiene 2 decimales");
                            }
                            else
                            {
                */
                if (((Double.Parse(totalImpuestosRetenidos)).CompareTo(redondeo(sumaImpuestosRetenidos))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalTaxesWithheld));
                }
                /*			}
                */
                // TotalFactura = TotalImporteBrutoAntesImpuestos + TotalImpuestosRepercutidos - TotalImpuestosRetenidos
                String totalfactura = ((XmlElement)totalesFactura.GetElementsByTagName("InvoiceTotal").Item(0)).FirstChild.Value;
                /*			if(decimales(totalfactura) != 2)
                            {
                                throw new Exception(76,"Totalfactura no tiene 2 decimales");
                            }
                            else
                            {
                */
                double total = Double.Parse(totalImporteBrutoAntesImpuestos) + (Double.Parse(totalImpuestosRepercutidos) - Double.Parse(totalImpuestosRetenidos));
                if (((Double.Parse(totalfactura)).CompareTo(redondeo(total))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorInvoiceTotal));
                }
                /*			}
                */
                // Comprobacion del nodo Subvenciones
                XmlElement subvenciones = (XmlElement)totalesFactura.GetElementsByTagName("Subsidies").Item(0);
                double sumaImportesSubvencion = 0;
                if (subvenciones != null)
                {
                    XmlNodeList nodosSubvenciones = subvenciones.GetElementsByTagName("Subsidy");
                    for (int j = 0; j < nodosSubvenciones.Count; j++)
                    {
                        XmlElement subvencion = ((XmlElement)nodosSubvenciones.Item(j));
                        // El número de decimales del PorcentajeSubvencion debe ser 4
                        XmlElement porcentajeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyRate").Item(0));
                        if (porcentajeSubvencion != null)
                        {
                            String valorPorcentajeSubvencion = porcentajeSubvencion.FirstChild.Value;
                            if (decimales(valorPorcentajeSubvencion) != 4)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSubsidyRate));
                            }
                        }
                        // El número de decimales del ImporteSubvencion debe ser 2
                        String importeSubvencion = ((XmlElement)subvencion.GetElementsByTagName("SubsidyAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeSubvencion) != 2)
                                            {
                                                throw new Exception(79,"ImporteSubvencion no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesSubvencion += Double.Parse(importeSubvencion);
                        /*					}
                        */
                    }
                }

                // Comprobacion del nodo Anticipos
                XmlElement anticipos = (XmlElement)totalesFactura.GetElementsByTagName("PaymentsonAccount").Item(0);
                double sumaImportesAnticipo = 0;
                if (anticipos != null)
                {
                    XmlNodeList nodosAnticipos = anticipos.GetElementsByTagName("PaymentOnAccount");
                    for (int j = 0; j < nodosAnticipos.Count; j++)
                    {
                        XmlElement anticipo = ((XmlElement)nodosAnticipos.Item(j));
                        // El número de decimales del ImporteAnticipo debe ser 2
                        String importeAnticipo = ((XmlElement)anticipo.GetElementsByTagName("PaymentOnAccountAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeAnticipo) != 2)
                                            {
                                                throw new Exception(80,"ImporteAnticipo no tiene 2 decimales");
                                            }
                                            else
                                            {
                        */
                        // vamos sumando todos los importes para una futura validacion
                        sumaImportesAnticipo += Double.Parse(importeAnticipo);
                        /*					}
                        */
                    }
                }

                // TotalAnticipos debe coincidir con el sumatorio de los importes de los anticipos
                XmlElement totalAnticipos = ((XmlElement)totalesFactura.GetElementsByTagName("TotalPaymentsOnAccount").Item(0));
                if (totalAnticipos != null)
                {
                    String valorTotalAnticipos = totalAnticipos.FirstChild.Value;
                    /*				if(decimales(valorTotalAnticipos) != 2)
                                    {
                                        throw new Exception(81,"TotalAnticipos no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    if (((Double.Parse(valorTotalAnticipos)).CompareTo(redondeo(sumaImportesAnticipo))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalPaymentsOnAccount));
                    }
                    /*				}
                    */
                }

                // TotalAPagar = TotalFactura - (Sumatorio de ImporteSubvencion + TotalAnticipos)
                String totalAPagarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalOutstandingAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAPagarFactura) != 2)
                            {
                                throw new Exception(83,"TotalAPagar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAPagarFactura = Double.Parse(totalfactura) - (sumaImportesSubvencion + sumaImportesAnticipo);
                if (((Double.Parse(totalAPagarFactura)).CompareTo(redondeo(sumaAPagarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalOutstandingAmount));
                    /*				}
                    */
                }

                // Comprobacion del nodo RetencionGarantia
                XmlElement retencionGarantia = (XmlElement)totalesFactura.GetElementsByTagName("AmountsWithheld").Item(0);
                double valorImporteRetencion = 0;
                if (retencionGarantia != null)
                {
                    // El número de decimales del PorcentajeRetencion debe ser 4
                    XmlElement porcentajeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingRate").Item(0));
                    if (porcentajeRetencion != null)
                    {
                        String valorPorcentajeRetencion = porcentajeRetencion.FirstChild.Value;
                        if (decimales(valorPorcentajeRetencion) != 4)
                        {
                            throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorWithholdingRate));
                        }
                    }
                    // El número de decimales del ImporteRetencion debe ser 2
                    String importeRetencion = ((XmlElement)retencionGarantia.GetElementsByTagName("WithholdingAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeRetencion) != 2)
                                    {
                                        throw new Exception(86,"ImporteRetencion no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    valorImporteRetencion = Double.Parse(importeRetencion);
                    /*				}
                    */
                }

                // TotalAEjecutar = TotalAPagar - ImporteRetencion
                String totalAEjecutarFactura = ((XmlElement)totalesFactura.GetElementsByTagName("TotalExecutableAmount").Item(0)).FirstChild.Value;
                /*			if(decimales(totalAEjecutarFactura) != 2)
                            {
                                throw new Exception(87,"TotalAEjecutar no tiene 2 decimales");
                            }
                            else
                            {
                */
                double sumaAEjecutarFactura = Double.Parse(totalAPagarFactura) - valorImporteRetencion;
                if (((Double.Parse(totalAEjecutarFactura)).CompareTo(redondeo(sumaAEjecutarFactura))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalExecutableAmount));
                }
                /*			}
                */
                // Detalles

                XmlElement detalles = ((XmlElement)factura.GetElementsByTagName("Items").Item(0));
                XmlNodeList nodosDetalles = detalles.GetElementsByTagName("InvoiceLine");
                double sumaImporteBruto = 0;
                for (int j = 0; j < nodosDetalles.Count; j++)
                {
                    XmlElement detalle = ((XmlElement)nodosDetalles.Item(j));

                    // El número de decimales del PrecioUnitarioSinImpuestos debe ser 2
                    String precioUnitarioSinImpuestos = ((XmlElement)detalle.GetElementsByTagName("UnitPriceWithoutTax").Item(0)).FirstChild.Value;
                    /*				if(decimales(precioUnitarioSinImpuestos) != 6)
                                    {
                                        throw new Exception(89,"PrecioUnitarioSinImpuestos no tiene 6 decimales");
                                    }
                    */
                    //Comprobar que CosteTotal = Cantidad * PrecioUnitarioSinImpuestos
                    String cantidad = ((XmlElement)detalle.GetElementsByTagName("Quantity").Item(0)).FirstChild.Value;
                    String costeTotal = ((XmlElement)detalle.GetElementsByTagName("TotalCost").Item(0)).FirstChild.Value;
                    /*				if(decimales(costeTotal) != 2)
                                    {
                                        throw new Exception(90,"CosteTotal no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double sumaCosteTotal = Double.Parse(precioUnitarioSinImpuestos) * Double.Parse(cantidad);
                    if (((Double.Parse(costeTotal)).CompareTo(redondeo(sumaCosteTotal))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTotalCost));
                    }
                    /*				}
                    */
                    // Comprobacion del nodo Descuentos
                    XmlElement descuentos = (XmlElement)detalle.GetElementsByTagName("DiscountsAndRebates").Item(0);
                    double sumaImportesDescuentoDetalle = 0;
                    if (descuentos != null)
                    {
                        XmlNodeList nodosDescuentos = descuentos.GetElementsByTagName("Discount");
                        for (int k = 0; k < nodosDescuentos.Count; k++)
                        {
                            XmlElement descuento = ((XmlElement)nodosDescuentos.Item(k));
                            // El número de decimales del PorcentajeDescuento debe ser 4
                            XmlElement porcentajeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountRate").Item(0));
                            if (porcentajeDescuento != null)
                            {
                                String valorPorcentajeDescuento = porcentajeDescuento.FirstChild.Value;
                                if (decimales(valorPorcentajeDescuento) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorDiscountRate));
                                }
                            }
                            // El número de decimales del ImporteDescuento debe ser 2
                            String importeDescuento = ((XmlElement)descuento.GetElementsByTagName("DiscountAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeDescuento) != 2)
                                                    {
                                                        throw new Exception(93,"ImporteDescuento no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesDescuentoDetalle += Double.Parse(importeDescuento);
                            /*						}
                            */
                        }
                    }

                    // Comprobacion del nodo Cargos
                    XmlElement cargos = (XmlElement)detalle.GetElementsByTagName("Charges").Item(0);
                    double sumaImportesCargoDetalle = 0;
                    if (cargos != null)
                    {
                        XmlNodeList nodosCargos = cargos.GetElementsByTagName("Charge");
                        for (int k = 0; k < nodosCargos.Count; k++)
                        {
                            XmlElement cargo = ((XmlElement)nodosCargos.Item(k));
                            // El número de decimales del PorcentajeCargo debe ser 4
                            XmlElement porcentajeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeRate").Item(0));
                            if (porcentajeCargo != null)
                            {
                                String valorPorcentajeCargo = porcentajeCargo.FirstChild.Value;
                                if (decimales(valorPorcentajeCargo) != 4)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorChargeRate));
                                }
                            }
                            // El número de decimales del ImporteCargo debe ser 2
                            String importeCargo = ((XmlElement)cargo.GetElementsByTagName("ChargeAmount").Item(0)).FirstChild.Value;
                            /*						if(decimales(importeCargo) != 2)
                                                    {
                                                        throw new Exception(95,"ImporteCargo no tiene 2 decimales");
                                                    }
                                                    else
                                                    {
                            */
                            // vamos sumando todos los importes para una futura validacion
                            sumaImportesCargoDetalle += Double.Parse(importeCargo);
                            /*						}
                            */
                        }
                    }

                    // Comprobar que ImporteBruto = CosteTotal - Sumatorio de ImporteDescuento + Sumatorio de ImporteCargo
                    String importeBruto = ((XmlElement)detalle.GetElementsByTagName("GrossAmount").Item(0)).FirstChild.Value;
                    /*				if(decimales(importeBruto) != 2)
                                    {
                                        throw new Exception(96,"ImporteBruto no tiene 2 decimales");
                                    }
                                    else
                                    {
                    */
                    double suma = Double.Parse(costeTotal) - sumaImportesDescuentoDetalle + sumaImportesCargoDetalle;
                    if (((Double.Parse(importeBruto)).CompareTo(redondeo(suma))) != 0)
                    {
                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorGrossAmount));
                    }
                    else
                    {
                        sumaImporteBruto += Double.Parse(importeBruto);
                    }
                    /*				}
                    */
                    // ImpuestosRetenidos
                    XmlElement baseImponibleDetalle = null;
                    XmlElement cuotaDetalle = null;
                    nl = detalle.GetElementsByTagName("TaxesWithheld");
                    if (nl.Count > 0)
                    {
                        XmlElement impuestosRetenidosDetalle = (XmlElement)nl.Item(0);
                        XmlNodeList nodosImpuestosRetenidosDetalle = impuestosRetenidosDetalle.GetElementsByTagName("Tax");
                        for (int k = 0; k < nodosImpuestosRetenidosDetalle.Count; k++)
                        {
                            XmlElement impuestoRetenido = ((XmlElement)nodosImpuestosRetenidosDetalle.Item(k));
                            baseImponibleDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxableBase").Item(0);
                            cuotaDetalle = (XmlElement)impuestoRetenido.GetElementsByTagName("TaxAmount").Item(0);
                            String importeBaseImponible = null;
                            String importeCuota = null;
                            String tipo = null;

                            // El número de decimales del PorcentajeImpuesto debe ser 2
                            XmlElement porcentajeImpuesto = ((XmlElement)impuestoRetenido.GetElementsByTagName("TaxRate").Item(0));
                            String valorPorcentajeImpuesto = null;
                            if (porcentajeImpuesto != null)
                            {
                                valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                                if (decimales(valorPorcentajeImpuesto) != 2)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesWithheldTaxRate));
                                }
                            }

                            if (moneda.Equals("EUR"))
                            {
                                if (baseImponibleDetalle != null)
                                {
                                    // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                                    importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                    /*								if(decimales(importeBaseImponible) != 2)
                                                                    {
                                                                        throw new Exception(109,"ImporteTotal de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }
                                    */
                                }
                                if (cuotaDetalle != null)
                                {
                                    importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                    /*								if(decimales(importeCuota) != 2)
                                                                    {
                                                                        throw new Exception(110,"ImporteTotal de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }
                                    */
                                }
                            }
                            else
                            {
                                if (baseImponibleDetalle != null)
                                {
                                    // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                                    nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                                    if (nl.Count == 0)
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesEquivalentInEuros));
                                    }
                                    // El número de decimales del cambio debe ser 2
                                    tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                    /*								if(decimales(tipo) != 2)
                                                                    {
                                                                        throw new Exception(112,"TipoCambio de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }
                                    */
                                    // El número de decimales del contravalor en euros debe ser 2
                                    importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                    /*								if(decimales(importeBaseImponible) != 2)
                                                                    {
                                                                        throw new Exception(113,"ContravalorEuros de la base imponible de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }					
                                    */
                                }
                                if (cuotaDetalle != null)
                                {
                                    nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                                    if (nl.Count == 0)
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountEquivalentInEuros));
                                    }
                                    // El número de decimales del cambio debe ser 2
                                    tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                    /*								if(decimales(tipo) != 2)
                                                                    {
                                                                        throw new Exception(115,"TipoCambio de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }
                                    */
                                    // El número de decimales del contravalor en euros debe ser 2
                                    importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                    /*								if(decimales(importeCuota) != 2)
                                                                    {
                                                                        throw new Exception(116,"ContravalorEuros de la cuota de ImpuestosRetenidos no tiene 2 decimales");
                                                                    }
                                    */
                                }
                            }

                            // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                            if (cuotaDetalle != null)
                            {
                                if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                                {
                                    double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                    if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxAmountPercentTaxableBase));
                                    }
                                }
                            }
                        }
                    }

                    // ImpuestosRepercutidos
                    XmlElement impuestosRepercutidosDetalle = (XmlElement)detalle.GetElementsByTagName("TaxesOutputs").Item(0);
                    XmlNodeList nodosImpuestosRepercutidosDetalle = impuestosRepercutidosDetalle.GetElementsByTagName("Tax");
                    for (int k = 0; k < nodosImpuestosRepercutidosDetalle.Count; k++)
                    {
                        XmlElement impuestoRepercutido = ((XmlElement)nodosImpuestosRepercutidosDetalle.Item(k));
                        baseImponibleDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxableBase").Item(0);
                        cuotaDetalle = (XmlElement)impuestoRepercutido.GetElementsByTagName("TaxAmount").Item(0);
                        String importeBaseImponible = null;
                        String importeCuota = null;
                        String tipo = null;

                        // El número de decimales del PorcentajeImpuesto debe ser 2
                        XmlElement porcentajeImpuesto = ((XmlElement)impuestoRepercutido.GetElementsByTagName("TaxRate").Item(0));
                        String valorPorcentajeImpuesto = null;
                        if (porcentajeImpuesto != null)
                        {
                            valorPorcentajeImpuesto = porcentajeImpuesto.FirstChild.Value;
                            if (decimales(valorPorcentajeImpuesto) != 2)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxRate));
                            }
                        }

                        if (moneda.Equals("EUR"))
                        {
                            if (baseImponibleDetalle != null)
                            {
                                // Si la moneda es euro, el ImporteTotal de la base imponible y de la cuota debe tener 2 decimales
                                importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeBaseImponible) != 2)
                                                            {
                                                                throw new Exception(99,"ImporteTotal de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }
                                */
                            }
                            if (cuotaDetalle != null)
                            {
                                importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("TotalAmount").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeCuota) != 2)
                                                            {
                                                                throw new Exception(100,"ImporteTotal de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }
                                */
                            }
                        }
                        else
                        {
                            if (baseImponibleDetalle != null)
                            {
                                // Si la moneda no es euro, deben existir los datos del contravalor tanto para la base imponible como para la cuota
                                nl = baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros");
                                if (nl.Count == 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxableBaseEquivalentInEuros));
                                }
                                // El número de decimales del cambio debe ser 2
                                tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                /*							if(decimales(tipo) != 2)
                                                            {
                                                                throw new Exception(102,"TipoCambio de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }
                                */
                                // El número de decimales del contravalor en euros debe ser 2
                                importeBaseImponible = ((XmlElement)baseImponibleDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeBaseImponible) != 2)
                                                            {
                                                                throw new Exception(103,"ContravalorEuros de la base imponible de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }					
                                */
                            }
                            if (cuotaDetalle != null)
                            {
                                nl = cuotaDetalle.GetElementsByTagName("EquivalentInEuros");
                                if (nl.Count == 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsTaxAmountEquivalentInEuros));
                                }
                                // El número de decimales del cambio debe ser 2
                                tipo = ((XmlElement)nl.Item(0)).FirstChild.Value;
                                /*							if(decimales(tipo) != 2)
                                                            {
                                                                throw new Exception(105,"TipoCambio de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }
                                */
                                // El número de decimales del contravalor en euros debe ser 2
                                importeCuota = ((XmlElement)cuotaDetalle.GetElementsByTagName("EquivalentInEuros").Item(0)).FirstChild.Value;
                                /*							if(decimales(importeCuota) != 2)
                                                            {
                                                                throw new Exception(106,"ContravalorEuros de la cuota de ImpuestosRepercutidos no tiene 2 decimales");
                                                            }
                                */
                            }
                        }

                        // Comprobamos que la cuota corresponde con la aplicación del porcentaje a la base imponible
                        if (cuotaDetalle != null)
                        {
                            if (importeBaseImponible != null && valorPorcentajeImpuesto != null)
                            {
                                double resultado = Double.Parse(String.Format("{0:0.00}", (Double.Parse(importeBaseImponible) * (Double.Parse(valorPorcentajeImpuesto))) / 100));
                                if (((Double.Parse(importeCuota)).CompareTo(redondeo(resultado))) != 0)
                                {
                                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorTaxesOutputsPercent));
                                }
                            }
                        }

                    }
                }

                // Comprobar que la suma de los importes brutos de los detalles coincide con el total
                if (((Double.Parse(totalImporteBruto)).CompareTo(redondeo(sumaImporteBruto))) != 0)
                {
                    throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorSumGrossAmount));
                }

                // DatosCobro

                nl = factura.GetElementsByTagName("PaymentDetails");
                if (nl.Count > 0)
                {
                    XmlElement datosCobro = (XmlElement)nl.Item(0);
                    XmlNodeList nodosVencimiento = datosCobro.GetElementsByTagName("Installment");
                    for (int j = 0; j < nodosVencimiento.Count; j++)
                    {
                        XmlElement vencimiento = ((XmlElement)nodosVencimiento.Item(j));

                        // El número de decimales del ImporteVencimiento debe ser 2
                        String importeVencimiento = ((XmlElement)vencimiento.GetElementsByTagName("InstallmentAmount").Item(0)).FirstChild.Value;
                        /*					if(decimales(importeVencimiento) != 2)
                                            {
                                                throw new Exception(119,"ImporteVencimiento no tiene 2 decimales");
                                            }
                        */
                        // Si FormaPago es "Trasferencia", el nodo CuentaAbono es obligatorio
                        String formaPago = ((XmlElement)vencimiento.GetElementsByTagName("PaymentMeans").Item(0)).FirstChild.Value;
                        if (formaPago.Equals("Transferencia"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeCredited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeCredited));
                            }
                            else
                            {
                                XmlElement cuentaAbono = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaAbono.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                        // Si FormaPago es "Recibo", el nodo CuentaCargo es obligatorio
                        else if (formaPago.Equals("Recibo"))
                        {
                            nl = vencimiento.GetElementsByTagName("AccountToBeDebited");
                            if (nl.Count == 0)
                            {
                                throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorAccountToBeDebited));
                            }
                            else
                            {
                                XmlElement cuentaCargo = (XmlElement)nl.Item(0);
                                XmlElement direccionOficinaNacional = ((XmlElement)cuentaCargo.GetElementsByTagName("BranchInSpainAddresst").Item(0));
                                //comprobamos que si se ha elegido DireccionOficinaNacional el codigoPais es ESP
                                if (direccionOficinaNacional != null)
                                {
                                    String codigoPais = ((XmlElement)direccionOficinaNacional.GetElementsByTagName("CountryCode").Item(0)).FirstChild.Value;
                                    if (!codigoPais.Equals("ESP"))
                                    {
                                        throw new Exception(msg.getMessage(ControlMessages.Msg.ErrorCountryCodeESP));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }


        /// <summary>
        /// Validación contable de CII
        /// </summary>
        /// <param name="doc">Documento xml con la facturae</param>
        public static void ValidationAccountingCII(String path)
        {
            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = true;
            doc.Load(path);
            ResultCIIValidation result = CIIValidation.AccountValidation(doc);
            if (!result.Success)
            {
                throw new Exception(result.MsgError);
            }
        }

        /// <summary>
        /// Validación contable de UBL
        /// </summary>
        /// <param name="doc">Documento xml con la facturae</param>
        public static void ValidationAccountingUBL(String path)
        {
            XmlDocument doc = new XmlDocument();
            doc.PreserveWhitespace = true;
            doc.Load(path);
            ResultUBLValidation result = UBLValidation.AccountValidation(doc);
            if (!result.Success)
            {
                throw new Exception(result.MsgError);
            }

        }


        /// <summary>
        /// Método que realiza la validación del esquema de Facturae.
        /// </summary>
        /// <param name="doc">Xml con la factura</param>
        public static void ValidationSchema(XmlDocument doc)
        {
        }

        /// <summary>
        /// Método que realiza la validación de la firma.
        /// </summary>
        /// <param name="xmlDocument">Xml con la factura firmada.</param>
        public static void SignedValidation(XmlDocument xmlDocument)
        {
        }


        /// <summary>
        /// Método que valida el CIF
        /// </summary>
        /// <param name="cif">Parámetro de tipo string que contiene el CIF a validar</param>
        /// <returns></returns>
        private static bool ValidarCIF(string cif)
        {
            //Si la letra inicial del CIF es una de estas el digito de control es un numero
            //string digitoControlNum = "ABDEFGHJUV";
            //Si la letra inicial del CIF es una de estas el digito de control es una letra
            string digitoControlLetra = "CKLMNPQRSW";
            //Posibles letras iniciales
            string letras = "ABCDEFGHJKLMNPQRSUVW";
            string digitoControl = string.Empty;
            int pares = 0;
            int impares = 0;
            bool esLetra = false;
            string letraInicial = cif.Substring(0, 1);
            //Comprobacion de longitud
            if (cif.Length != 9)
            {
                Console.WriteLine("El Cif debe tener 9 dígitos");
                return false;
            }
            //Comprobacion de letra incial
            if (letras.IndexOf(letraInicial.ToUpper()) == -1)
            {
                Console.WriteLine("El comienzo del Cif no es válido");
                return false;
            }
            //Comprobacion de los 7 digitos numéricos
            if (!IsNumeric(cif.Substring(1, 7)))
            {
                Console.WriteLine("El CIF contiene caracteres no validos");
                return false;
            }
            //Comprobación para saber si el digito de control es un numero o una letra
            if (digitoControlLetra.Contains(letraInicial.ToUpper()))
            {
                esLetra = true;
            }
            //Suma de los numeros que estan en las posiciones pares
            for (int i = 2; i < 8; i++)
            {
                pares = pares + int.Parse(cif.Substring(i, 1));
                i++;
            }
            //Suma de los numeros que estan en las posiciones impare
            //Por cada numero de una posicion impar se multiplica por 2 y se suman las cifras del resultado entre si
            for (int i = 1; i < 9; i++)
            {
                int nn = 2 * int.Parse(cif.Substring(i, 1));
                if (nn > 9) nn = 1 + (nn - 10);
                impares = impares + nn;
                i++;
            }
            //Calculo del digito de control
            //Se suman los pares e impares,se coge el digito de las unidades del resultado y se le resta a 10
            //Ese digito será un valor del 0 al 9 en el caso de ser numerico o de la A a la J
            //en el caso de ser una letra.
            int parcial = pares + impares;
            int control = (10 - (parcial % 10)) % 10;
            //if (control == 10)
            //    control = 0;
            if (esLetra)
            {
                string[] l = { "J", "A", "B", "C", "D", "E", "F", "G", "H", "I" };
                digitoControl = l[control];
            }
            else
            {
                digitoControl = control.ToString();
            }
            //Comrobación del digito de control
            if (digitoControl != cif.Substring(8, 1).ToUpper())
            {
                Console.WriteLine("El Cif no es válido");
                return false;
            }
            Console.WriteLine("Cif valido");
            return true;
        }

        /// <summary>
        /// Método que validad el DNI
        /// </summary>
        /// <param name="dni">Parámetro de tipo string que contiene el DNI a validar</param>
        /// <returns></returns>
        private static bool ValidarDNI(string dni)
        {

            if (new Regex("[0-9]{8}[A-Za-z]").Match(dni).Success)
            {
                return ("TRWAGMYFPDXBNJZSQVHLCKE"[(int)long.Parse(dni.Substring(0, 8)) % 23].ToString() == dni.Substring(8).ToString().ToUpper());
            }
            else
            {
                return false;
            }


        }

        /// <summary>
        /// Método que valida la estructura de una direccion de correo electrónico
        /// </summary>
        /// <param name="email">Parámetro de tipo string que contiene la dirección a validar</param>
        /// <returns></returns>
        public static bool ValidarEmail(string email)
        {
            string expresion = "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";

            if (Regex.IsMatch(email, expresion))
            {
                if (Regex.Replace(email, expresion, String.Empty).Length == 0)
                { return true; }
                else
                { return false; }
            }
            else
            { return false; }
        }

        /// <summary>
        /// Método que valida si un string es un numero o no
        /// </summary>
        /// <param name="num">Parámetro de tipo string que contiene el numero a validar</param>
        /// <returns></returns>
        public static bool IsNumeric(string num)
        {
            try
            {
                double.Parse(num);
                return true;
            }
            catch (Exception)
            {
                return false;

            }
        }

        /// <summary>
        /// Método que valida si una fecha está bien contruida
        /// </summary>
        /// <param name="fecha">Parámetro de tipo string que contiene la fecha a validar</param>
        /// <returns></returns>
        public static bool ValidarFecha(string fecha)
        {
            try
            {
                CultureInfo cult = Thread.CurrentThread.CurrentCulture;
                DateTime myDT = DateTime.Parse(fecha, cult);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// Método que valida un teléfono
        /// </summary>
        /// <param name="tel">Parámetro de tipo string que contiene el teléfono a validar</param>
        /// <returns></returns>
        public static bool ValidarTelefono(string tel)
        {
            if (tel.Length > 15)
                return false;
            else
            {
                if (!IsNumeric(tel))
                    return false;
            }
            return true;


        }

        /// <summary>
        /// Método que valida un código postal
        /// </summary>
        /// <param name="cp">Parámetro de tipo string que contiene el CP a validar</param>
        /// <returns></returns>
        public static bool ValidarCP(string cp)
        {
            if (cp.Length != 5)
                return false;
            else
            {
                if (!IsNumeric(cp))
                    return false;
            }
            return true;


        }

        #endregion

        #region "Private Methods"

        /// <summary>
        /// Método que devuelve el número de decimales
        /// </summary>
        /// <param name="numero">String de un número</param>
        /// <returns>Número de decimales</returns>
        private static int decimales(String numero)
        {
            int i = numero.IndexOf('.');
            return (i == -1) ? 0 : numero.Length - i - 1;
        }

        /// <summary>
        /// Método que redondea un número
        /// </summary>
        /// <param name="numero">Número que hay que redondear</param>
        /// <returns>Devuevle el número redondeado</returns>
        //private static double redondeo(double numero)
        //{
        //    long numeroFinal;
        //    if (numero >= 0)
        //    {
        //        numeroFinal = ((long)Math.Round((numero * (Math.Pow(10, 2)))));
        //    }
        //    else
        //    {
        //        numeroFinal = (-(long)Math.Round((-numero * (Math.Pow(10,2)))));
        //    }
        //    return (double)numeroFinal / (100);
        //}

        private static double redondeo(double numero)
        {
            double multi = Math.Pow(10.0d, (double)2);

            if (numero < 0)
                return (-(long)((-numero * multi) + 0.5d)) / multi;
            else
                return ((long)((numero * multi) + 0.5d)) / multi;
        }


        #endregion

        public static CountryType convertToCountryType(string country)
        {
            try
            {
                return (CountryType)Enum.Parse(typeof(CountryType), country);
            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        public static string ConvertToString(Enum e)
        {
            // Get the Type of the enum
            Type t = e.GetType();

            // Get the FieldInfo for the member field with the enums name
            FieldInfo info = t.GetField(e.ToString("G"));

            // Check to see if the XmlEnumAttribute is defined on this field
            if (!info.IsDefined(typeof(XmlEnumAttribute), false))
            {
                // If no XmlEnumAttribute then return the string version of the enum.
                return e.ToString("G");
            }

            // Get the XmlEnumAttribute
            object[] o = info.GetCustomAttributes(typeof(XmlEnumAttribute), false);
            XmlEnumAttribute att = (XmlEnumAttribute)o[0];
            return att.Name;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cif"></param>
        /// <param name="country"></param>
        /// <returns></returns>
        public static bool validarCif(string cif, string country)
        {
            bool valido = false;
            bool countryvalido = false;
            bool idvalido = false;

            if (string.IsNullOrEmpty(cif))
            {
                throw new Exception("no se ha indicado un cif/nif valido");
            }
            else if (cif.Length == 11)
            {
                string countrycode = cif.Substring(0, 2);
                string nif = cif.Substring(2);
                countryvalido = validarCountryCode(country, countrycode);

                char[] c1 = nif.ToCharArray();
                if (!Char.IsDigit(c1[0]))
                {
                    idvalido = InvoiceValidations.ValidarCIF(nif);
                }
                else
                {
                    idvalido = InvoiceValidations.ValidarDNI(nif);
                }

                if (countryvalido && idvalido)
                    valido = true;
            }
            else
            {
                if (!Char.IsDigit(cif.ToCharArray()[0]))
                {
                    valido = InvoiceValidations.ValidarCIF(cif);
                }
                else
                {
                    valido = InvoiceValidations.ValidarDNI(cif);
                }
            }
            return valido;


        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="countrycode3">codigo de pais en tres letras</param>
        /// <param name="countrycode2">codigo de pais en dos letras</param>
        public static bool validarCountryCode(string countrycode3, string countrycode2)
        {
            bool valido = false;
            CountryType country2;
            try
            {
                country2 = convertToCountryType(countrycode3);
                string code = ConvertToString(country2);
                if (countrycode2.ToUpper().Equals(code))
                {
                    valido = true;
                }
            }
            catch (Exception)
            {
            }
            return valido;
        }

        /// <summary>
        /// Enumerado de paises con los codigos iso en dos y tres letras
        /// </summary>
        public enum CountryType
        {

            [XmlEnumAttribute("AF")]
            AFG,

            [XmlEnumAttribute("AL")]
            ALB,

            [XmlEnumAttribute("AS")]
            ASM,

            [XmlEnumAttribute("AD")]
            AND,

            [XmlEnumAttribute("AO")]
            AGO,

            [XmlEnumAttribute("AI")]
            AIA,

            [XmlEnumAttribute("AG")]
            ATG,

            [XmlEnumAttribute("AR")]
            ARG,

            [XmlEnumAttribute("AM")]
            ARM,

            [XmlEnumAttribute("AW")]
            ABW,

            [XmlEnumAttribute("AU")]
            AUS,

            [XmlEnumAttribute("AT")]
            AUT,

            [XmlEnumAttribute("AZ")]
            AZE,

            [XmlEnumAttribute("BS")]
            BHS,

            [XmlEnumAttribute("BH")]
            BHR,

            [XmlEnumAttribute("BD")]
            BGD,

            [XmlEnumAttribute("BB")]
            BRB,

            [XmlEnumAttribute("BY")]
            BLR,

            [XmlEnumAttribute("BE")]
            BEL,

            [XmlEnumAttribute("BZ")]
            BLZ,

            [XmlEnumAttribute("BJ")]
            BEN,

            [XmlEnumAttribute("BM")]
            BMU,

            [XmlEnumAttribute("BT")]
            BTN,

            [XmlEnumAttribute("BO")]
            BOL,

            [XmlEnumAttribute("BA")]
            BIH,

            [XmlEnumAttribute("BW")]
            BWA,

            [XmlEnumAttribute("BR")]
            BRA,

            [XmlEnumAttribute("BN")]
            BRN,

            [XmlEnumAttribute("BG")]
            BGR,

            [XmlEnumAttribute("BF")]
            BFA,

            [XmlEnumAttribute("BI")]
            BDI,

            [XmlEnumAttribute("KH")]
            KHM,

            [XmlEnumAttribute("CM")]
            CMR,

            [XmlEnumAttribute("CA")]
            CAN,

            [XmlEnumAttribute("CV")]
            CPV,

            [XmlEnumAttribute("KY")]
            CYM,

            [XmlEnumAttribute("CF")]
            CAF,

            [XmlEnumAttribute("TD")]
            TCD,

            [XmlEnumAttribute("CL")]
            CHL,

            [XmlEnumAttribute("CN")]
            CHN,

            [XmlEnumAttribute("CD")]
            COD,

            [XmlEnumAttribute("CO")]
            COL,

            [XmlEnumAttribute("KM")]
            COM,

            [XmlEnumAttribute("CG")]
            COG,

            [XmlEnumAttribute("CK")]
            COK,

            [XmlEnumAttribute("CR")]
            CRI,

            [XmlEnumAttribute("CI")]
            CIV,

            [XmlEnumAttribute("CV")]
            HRV,

            [XmlEnumAttribute("CU")]
            CUB,

            [XmlEnumAttribute("CY")]
            CYP,

            [XmlEnumAttribute("CZ")]
            CZE,

            [XmlEnumAttribute("DZ")]
            DZA,

            [XmlEnumAttribute("DK")]
            DNK,

            [XmlEnumAttribute("DJ")]
            DJI,

            [XmlEnumAttribute("DM")]
            DMA,

            [XmlEnumAttribute("DO")]
            DOM,

            [XmlEnumAttribute("EC")]
            ECU,

            [XmlEnumAttribute("EG")]
            EGY,

            [XmlEnumAttribute("SV")]
            SLV,

            [XmlEnumAttribute("GQ")]
            GNQ,

            [XmlEnumAttribute("ER")]
            ERI,

            [XmlEnumAttribute("EE")]
            EST,

            [XmlEnumAttribute("ET")]
            ETH,

            [XmlEnumAttribute("FK")]
            FLK,

            [XmlEnumAttribute("FO")]
            FRO,

            [XmlEnumAttribute("FJ")]
            FJI,

            [XmlEnumAttribute("FI")]
            FIN,

            [XmlEnumAttribute("FR")]
            FRA,

            [XmlEnumAttribute("GF")]
            GUF,

            [XmlEnumAttribute("PF")]
            PYF,

            [XmlEnumAttribute("GA")]
            GAB,

            [XmlEnumAttribute("GM")]
            GMB,

            [XmlEnumAttribute("GE")]
            GEO,

            [XmlEnumAttribute("GG")]
            GGY,

            [XmlEnumAttribute("DE")]
            DEU,

            [XmlEnumAttribute("GH")]
            GHA,

            [XmlEnumAttribute("GI")]
            GIB,

            [XmlEnumAttribute("GR")]
            GRC,

            [XmlEnumAttribute("GL")]
            GRL,

            [XmlEnumAttribute("GD")]
            GRD,

            [XmlEnumAttribute("GP")]
            GLP,

            [XmlEnumAttribute("GU")]
            GUM,

            [XmlEnumAttribute("GT")]
            GTM,

            [XmlEnumAttribute("GN")]
            GIN,

            [XmlEnumAttribute("GW")]
            GNB,

            [XmlEnumAttribute("GY")]
            GUY,

            [XmlEnumAttribute("HT")]
            HTI,

            [XmlEnumAttribute("HN")]
            HND,

            [XmlEnumAttribute("HK")]
            HKG,

            [XmlEnumAttribute("HU")]
            HUN,

            [XmlEnumAttribute("IS")]
            ISL,

            [XmlEnumAttribute("IN")]
            IND,

            [XmlEnumAttribute("ID")]
            IDN,

            [XmlEnumAttribute("IM")]
            IMN,

            [XmlEnumAttribute("IR")]
            IRN,

            [XmlEnumAttribute("IQ")]
            IRQ,

            [XmlEnumAttribute("IE")]
            IRL,

            [XmlEnumAttribute("IL")]
            ISR,

            [XmlEnumAttribute("IT")]
            ITA,

            [XmlEnumAttribute("JM")]
            JAM,

            [XmlEnumAttribute("JE")]
            JEY,

            [XmlEnumAttribute("JP")]
            JPN,

            [XmlEnumAttribute("JO")]
            JOR,

            [XmlEnumAttribute("KZ")]
            KAZ,

            [XmlEnumAttribute("KE")]
            KEN,

            [XmlEnumAttribute("KI")]
            KIR,

            [XmlEnumAttribute("KP")]
            PRK,

            [XmlEnumAttribute("KR")]
            KOR,

            [XmlEnumAttribute("KW")]
            KWT,

            [XmlEnumAttribute("KG")]
            KGZ,

            [XmlEnumAttribute("LA")]
            LAO,

            [XmlEnumAttribute("LV")]
            LVA,

            [XmlEnumAttribute("LB")]
            LBN,

            [XmlEnumAttribute("LS")]
            LSO,

            [XmlEnumAttribute("LR")]
            LBR,

            [XmlEnumAttribute("EC")]
            LBY,

            [XmlEnumAttribute("LI")]
            LIE,

            [XmlEnumAttribute("LT")]
            LTU,

            [XmlEnumAttribute("LU")]
            LUX,

            [XmlEnumAttribute("MO")]
            MAC,

            [XmlEnumAttribute("MK")]
            MKD,

            [XmlEnumAttribute("MG")]
            MDG,

            [XmlEnumAttribute("MW")]
            MWI,

            [XmlEnumAttribute("MY")]
            MYS,

            [XmlEnumAttribute("MV")]
            MDV,

            [XmlEnumAttribute("ML")]
            MLI,

            [XmlEnumAttribute("MT")]
            MLT,

            [XmlEnumAttribute("LU")]
            MHL,

            [XmlEnumAttribute("MQ")]
            MTQ,

            [XmlEnumAttribute("MR")]
            MRT,

            [XmlEnumAttribute("MU")]
            MUS,

            [XmlEnumAttribute("YT")]
            MYT,

            [XmlEnumAttribute("MX")]
            MEX,

            [XmlEnumAttribute("FM")]
            FSM,

            [XmlEnumAttribute("MD")]
            MDA,

            [XmlEnumAttribute("MC")]
            MCO,

            [XmlEnumAttribute("ME")]
            MNE,

            [XmlEnumAttribute("MN")]
            MNG,

            [XmlEnumAttribute("MS")]
            MSR,

            [XmlEnumAttribute("MA")]
            MAR,

            [XmlEnumAttribute("MZ")]
            MOZ,

            [XmlEnumAttribute("MM")]
            MMR,

            [XmlEnumAttribute("NA")]
            NAM,

            [XmlEnumAttribute("NR")]
            NRU,

            [XmlEnumAttribute("NP")]
            NPL,

            [XmlEnumAttribute("NL")]
            NLD,

            [XmlEnumAttribute("AN")]
            ANT,

            [XmlEnumAttribute("NC")]
            NCL,

            [XmlEnumAttribute("NZ")]
            NZL,

            [XmlEnumAttribute("NI")]
            NIC,

            [XmlEnumAttribute("NE")]
            NER,

            [XmlEnumAttribute("NG")]
            NGA,

            [XmlEnumAttribute("NU")]
            NIU,

            [XmlEnumAttribute("NF")]
            NFK,

            [XmlEnumAttribute("MP")]
            MNP,

            [XmlEnumAttribute("NO")]
            NOR,

            [XmlEnumAttribute("OM")]
            OMN,

            [XmlEnumAttribute("PK")]
            PAK,

            [XmlEnumAttribute("PW")]
            PLW,

            [XmlEnumAttribute("PA")]
            PAN,

            [XmlEnumAttribute("PG")]
            PNG,

            [XmlEnumAttribute("PY")]
            PRY,

            [XmlEnumAttribute("PS")]
            PSE,

            [XmlEnumAttribute("PE")]
            PER,

            [XmlEnumAttribute("PH")]
            PHL,

            [XmlEnumAttribute("PN")]
            PCN,

            [XmlEnumAttribute("PL")]
            POL,

            [XmlEnumAttribute("PT")]
            PRT,

            [XmlEnumAttribute("PR")]
            PRI,

            [XmlEnumAttribute("QA")]
            QAT,

            [XmlEnumAttribute("RE")]
            REU,

            [XmlEnumAttribute("RO")]
            ROU,

            [XmlEnumAttribute("RU")]
            RUS,

            [XmlEnumAttribute("RW")]
            RWA,

            [XmlEnumAttribute("KN")]
            KNA,

            [XmlEnumAttribute("LC")]
            LCA,

            [XmlEnumAttribute("VC")]
            VCT,

            [XmlEnumAttribute("WS")]
            WSM,

            [XmlEnumAttribute("SM")]
            SMR,

            [XmlEnumAttribute("ST")]
            STP,

            [XmlEnumAttribute("SA")]
            SAU,

            [XmlEnumAttribute("SN")]
            SEN,

            [XmlEnumAttribute("RS")]
            SRB,

            [XmlEnumAttribute("SC")]
            SYC,

            [XmlEnumAttribute("SL")]
            SLE,

            [XmlEnumAttribute("SG")]
            SGP,

            [XmlEnumAttribute("SK")]
            SVK,

            [XmlEnumAttribute("SI")]
            SVN,

            [XmlEnumAttribute("SB")]
            SLB,

            [XmlEnumAttribute("SO")]
            SOM,

            [XmlEnumAttribute("ZA")]
            ZAF,

            [XmlEnumAttribute("ES")]
            ESP,

            [XmlEnumAttribute("LK")]
            LKA,

            [XmlEnumAttribute("SH")]
            SHN,

            [XmlEnumAttribute("PM")]
            SPM,

            [XmlEnumAttribute("SD")]
            SDN,

            [XmlEnumAttribute("SR")]
            SUR,

            [XmlEnumAttribute("SJ")]
            SJM,

            [XmlEnumAttribute("SZ")]
            SWZ,

            [XmlEnumAttribute("SE")]
            SWE,

            [XmlEnumAttribute("CH")]
            CHE,

            [XmlEnumAttribute("SY")]
            SYR,

            [XmlEnumAttribute("TW")]
            TWN,

            [XmlEnumAttribute("TJ")]
            TJK,

            [XmlEnumAttribute("TZ")]
            TZA,

            [XmlEnumAttribute("TH")]
            THA,

            [XmlEnumAttribute("TG")]
            TGO,

            [XmlEnumAttribute("TK")]
            TKL,

            [XmlEnumAttribute("TO")]
            TON,

            [XmlEnumAttribute("TT")]
            TTO,

            [XmlEnumAttribute("TN")]
            TUN,

            [XmlEnumAttribute("TR")]
            TUR,

            [XmlEnumAttribute("TM")]
            TKM,

            [XmlEnumAttribute("TL")]
            TLS,

            [XmlEnumAttribute("TC")]
            TCA,

            [XmlEnumAttribute("TV")]
            TUV,

            [XmlEnumAttribute("UG")]
            UGA,

            [XmlEnumAttribute("UA")]
            UKR,

            [XmlEnumAttribute("AE")]
            ARE,

            [XmlEnumAttribute("GB")]
            GBR,

            [XmlEnumAttribute("US")]
            USA,

            [XmlEnumAttribute("UY")]
            URY,

            [XmlEnumAttribute("UZ")]
            UZB,

            [XmlEnumAttribute("VU")]
            VUT,

            [XmlEnumAttribute("VA")]
            VAT,

            [XmlEnumAttribute("VE")]
            VEN,

            [XmlEnumAttribute("VN")]
            VNM,

            [XmlEnumAttribute("VG")]
            VGB,

            [XmlEnumAttribute("VI")]
            VIR,

            [XmlEnumAttribute("WL")]
            WLF,

            [XmlEnumAttribute("EH")]
            ESH,

            [XmlEnumAttribute("YE")]
            YEM,

            [XmlEnumAttribute("ZM")]
            ZMB,

            [XmlEnumAttribute("ZW")]
            ZWE,
        }
    }
}
